anyhow_std/process/
child.rs

1use crate::process::{ExitStatus, Output};
2use anyhow::Context;
3use std::ops::Deref;
4use std::process::{ChildStderr, ChildStdin, ChildStdout};
5
6/// Wrap [std::process::Child] to provide the command as error context
7#[derive(Debug)]
8pub struct Child {
9    pub stdin: Option<ChildStdin>,
10    pub stdout: Option<ChildStdout>,
11    pub stderr: Option<ChildStderr>,
12    child: std::process::Child,
13    cmddesc: String,
14}
15
16impl From<(std::process::Child, String)> for Child {
17    fn from((mut child, cmddesc): (std::process::Child, String)) -> Self {
18        Child {
19            stdin: child.stdin.take(),
20            stdout: child.stdout.take(),
21            stderr: child.stderr.take(),
22            child,
23            cmddesc,
24        }
25    }
26}
27
28impl Deref for Child {
29    type Target = std::process::Child;
30
31    fn deref(&self) -> &Self::Target {
32        &self.child
33    }
34}
35
36impl Child {
37    /// Override [std::process::Child::kill] with the command as error context
38    pub fn kill(&mut self) -> anyhow::Result<()> {
39        self.child.kill().context(self.cmddesc.clone())
40    }
41
42    /// Override [std::process::Child::wait] with the command as error context
43    pub fn wait(&mut self) -> anyhow::Result<ExitStatus> {
44        self.child
45            .wait()
46            .map(|es| ExitStatus::from((es, self.cmddesc.clone())))
47            .context(self.cmddesc.clone())
48    }
49
50    /// Override [std::process::Child::try_wait] with the command as error context
51    pub fn try_wait(&mut self) -> anyhow::Result<Option<ExitStatus>> {
52        self.child
53            .try_wait()
54            .map(|optes| optes.map(|es| ExitStatus::from((es, self.cmddesc.clone()))))
55            .context(self.cmddesc.clone())
56    }
57
58    /// Override [std::process::Child::wait_with_output] with the command as error context
59    pub fn wait_with_output(self) -> anyhow::Result<Output> {
60        self.child
61            .wait_with_output()
62            .map(|o| Output::wrap(o, self.cmddesc.clone()))
63            .context(self.cmddesc)
64    }
65}