From e44dab54467998ac7b4dec36484bc7dc3b8a5af2 Mon Sep 17 00:00:00 2001 From: Schneems Date: Thu, 5 Jun 2025 16:53:55 -0500 Subject: [PATCH] Implement `TryFrom` for `tokio::process::Child` Currently, you can turn a `std::process::Command` into a `tokio::process::Command`, however, if you have a `std::process::Child` there is no way to turn it into a `tokio::process::Child`. This provides a mechanism. ## Context The use case I'm after is this: I have a small crate for running commands in Rust. I was wondering what a `tokio` feature might look like when I hit a bit of a snag. I can't find a reliable way to convert a `std::process:Child` into something `await`-able. The primary interface is this trait https://docs.rs/fun_run/0.6.0/fun_run/trait.CommandWithName.html. It is implemented for `Command` and `&mut Command`. If I want to add a feature flagged `async fn spawn` for `tokio::process::Command`, then I also need a way to reproduce the same interface in my other already-existing implementations. My thought was that for the default implementation, I can produce a regular `std::process::Child` and then, if I can turn it into a `tokio::process::Child`. Then I can standardize on that interface. --- tokio/CHANGELOG.md | 6 ++++++ tokio/src/process/mod.rs | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/tokio/CHANGELOG.md b/tokio/CHANGELOG.md index 27f84c867f4..9e1b7f1a57e 100644 --- a/tokio/CHANGELOG.md +++ b/tokio/CHANGELOG.md @@ -4,6 +4,12 @@ This fixes a regression on the wasm32-unknown-unknown target, where code that previously did not panic due to calls to `Instant::now()` started failing. This is due to the stabilization of the first time-based metric. +### Added + +- process: Implement `TryFrom` for `tokio::process::Child` ([#7388]) + +[#7388]: https://github.com/tokio-rs/tokio/pull/7388 + ### Fixed - Disable time-based metrics on wasm32-unknown-unknown ([#7322]) diff --git a/tokio/src/process/mod.rs b/tokio/src/process/mod.rs index eba17cff3a7..402a56d8d1b 100644 --- a/tokio/src/process/mod.rs +++ b/tokio/src/process/mod.rs @@ -1212,6 +1212,24 @@ pub struct Child { pub stderr: Option, } +impl TryFrom for Child { + type Error = io::Error; + + fn try_from(value: StdChild) -> io::Result { + let spawned_child = imp::build_child(value)?; + + Ok(Child { + child: FusedChild::Child(ChildDropGuard { + inner: spawned_child.child, + kill_on_drop: false, + }), + stdin: spawned_child.stdin.map(|inner| ChildStdin { inner }), + stdout: spawned_child.stdout.map(|inner| ChildStdout { inner }), + stderr: spawned_child.stderr.map(|inner| ChildStderr { inner }), + }) + } +} + impl Child { /// Returns the OS-assigned process identifier associated with this child /// while it is still running.