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
use std::borrow::Borrow;
use std::fmt::Debug;

#[cfg(doc)]
use std::process::Child;
#[cfg(doc)]
use std::process::Command;

#[cfg(doc)]
use crate::ChildExt;
use crate::CommandDisplay;
#[cfg(doc)]
use crate::OutputContext;

/// A [`Child`] process combined with context about the [`Command`] that produced it.
///
/// The context information stored in this type is used to produce diagnostics in [`ChildExt`].
///
/// See: [`OutputContext`].
pub struct ChildContext<C> {
    pub(crate) child: C,
    pub(crate) command: Box<dyn CommandDisplay>,
}

impl<C> ChildContext<C> {
    /// Get the child process.
    pub fn into_child(self) -> C {
        self.child
    }

    /// Get a reference to the child process.
    pub fn child(&self) -> &C {
        &self.child
    }

    /// Get a mutable reference to the child process.
    pub fn child_mut(&mut self) -> &mut C {
        &mut self.child
    }

    /// Get a reference to the command which produced this child process.
    pub fn command(&self) -> &dyn CommandDisplay {
        self.command.borrow()
    }
}

impl<C> Debug for ChildContext<C>
where
    C: Debug,
{
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("ChildContext")
            .field("child", &self.child)
            .field("command", &self.command.to_string())
            .finish()
    }
}