1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
use std::{
io::Result,
process::{ExitStatus, Output},
};
use super::AsyncGroupChild;
use tokio::process::Child;
/// Wrapper around a process child, be it grouped or ungrouped.
///
/// This is a helper which erases that a [`tokio::process::Child`] is a different type than an
/// [`AsyncGroupChild`]. It forwards to the corresponding method on the inner type.
#[derive(Debug)]
pub enum ErasedChild {
/// A grouped process child.
Grouped(AsyncGroupChild),
/// An ungrouped process child.
Ungrouped(Child),
}
impl ErasedChild {
/// Returns the OS-assigned process (group) identifier.
///
/// - Grouped: [`AsyncGroupChild::id`]
/// - Ungrouped: [`Child::id`]
pub fn id(&mut self) -> Option<u32> {
match self {
Self::Grouped(c) => c.id(),
Self::Ungrouped(c) => c.id(),
}
}
/// Forces the child to exit.
///
/// - Grouped: [`AsyncGroupChild::kill`]
/// - Ungrouped: [`Child::kill`]
pub async fn kill(&mut self) -> Result<()> {
match self {
Self::Grouped(c) => c.kill().await,
Self::Ungrouped(c) => c.kill().await,
}
}
/// Attempts to force the child to exit, but does not wait for the request to take effect.
///
/// - Grouped: [`AsyncGroupChild::start_kill`]
/// - Ungrouped: [`Child::start_kill`]
pub fn start_kill(&mut self) -> Result<()> {
match self {
Self::Grouped(c) => c.start_kill(),
Self::Ungrouped(c) => c.start_kill(),
}
}
/// Attempts to collect the exit status of the child if it has already exited.
///
/// - Grouped: [`AsyncGroupChild::try_wait`]
/// - Ungrouped: [`Child::try_wait`]
pub fn try_wait(&mut self) -> Result<Option<ExitStatus>> {
match self {
Self::Grouped(c) => c.try_wait(),
Self::Ungrouped(c) => c.try_wait(),
}
}
/// Waits for the process to exit, and returns its exit status.
///
/// - Grouped: [`AsyncGroupChild::wait`]
/// - Ungrouped: [`Child::wait`]
pub async fn wait(&mut self) -> Result<ExitStatus> {
match self {
Self::Grouped(c) => c.wait().await,
Self::Ungrouped(c) => c.wait().await,
}
}
/// Waits for the process to exit, and returns its exit status.
///
/// - Grouped: [`AsyncGroupChild::wait_with_output`]
/// - Ungrouped: [`Child::wait_with_output`]
pub async fn wait_with_output(self) -> Result<Output> {
match self {
Self::Grouped(c) => c.wait_with_output().await,
Self::Ungrouped(c) => c.wait_with_output().await,
}
}
/// Sends a Unix signal to the process.
///
/// - Grouped: [`AsyncGroupChild::signal`]
/// - Ungrouped: [`Child::signal`]
#[cfg(unix)]
pub fn signal(&self, sig: crate::Signal) -> Result<()> {
use crate::UnixChildExt;
match self {
Self::Grouped(c) => c.signal(sig),
Self::Ungrouped(c) => c.signal(sig),
}
}
}