nu_protocol/pipeline/
out_dest.rs

1use std::{fs::File, io, process::Stdio, sync::Arc};
2
3/// Describes where to direct the stdout or stderr output stream of external command to.
4#[derive(Debug, Clone)]
5pub enum OutDest {
6    /// Redirect the stdout and/or stderr of one command as the input for the next command in the pipeline.
7    ///
8    /// The output pipe will be available as the `stdout` of [`ChildProcess`](crate::process::ChildProcess).
9    ///
10    /// If stdout and stderr are both set to `Pipe`,
11    /// then they will combined into the `stdout` of [`ChildProcess`](crate::process::ChildProcess).
12    Pipe,
13    /// Redirect the stdout and/or stderr of one command as the input for the next command in the pipeline.
14    ///
15    /// The output stream(s) will be available in the `stdout` or `stderr` of [`ChildProcess`](crate::process::ChildProcess).
16    ///
17    /// This is similar to `Pipe` but will never combine stdout and stderr
18    /// or place an external command's stderr into `stdout` of [`ChildProcess`](crate::process::ChildProcess).
19    PipeSeparate,
20    /// Signifies the result of the pipeline will be immediately collected into a value after this command.
21    ///
22    /// So, it is fine to collect the stream ahead of time in the current command.
23    Value,
24    /// Ignore output.
25    ///
26    /// This will forward output to the null device for the platform.
27    Null,
28    /// Output to nushell's stdout or stderr (only for external commands).
29    ///
30    /// This causes external commands to inherit nushell's stdout or stderr. This also causes
31    /// [`ListStream`](crate::ListStream)s to be drained, but not to be printed.
32    Inherit,
33    /// Print to nushell's stdout or stderr.
34    ///
35    /// This is just like `Inherit`, except that [`ListStream`](crate::ListStream)s and
36    /// [`Value`](crate::Value)s are also printed.
37    Print,
38    /// Redirect output to a file.
39    File(Arc<File>), // Arc<File>, since we sometimes need to clone `OutDest` into iterators, etc.
40}
41
42impl From<File> for OutDest {
43    fn from(file: File) -> Self {
44        Arc::new(file).into()
45    }
46}
47
48impl From<Arc<File>> for OutDest {
49    fn from(file: Arc<File>) -> Self {
50        Self::File(file)
51    }
52}
53
54impl TryFrom<&OutDest> for Stdio {
55    type Error = io::Error;
56
57    fn try_from(out_dest: &OutDest) -> Result<Self, Self::Error> {
58        match out_dest {
59            OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value => Ok(Self::piped()),
60            OutDest::Null => Ok(Self::null()),
61            OutDest::Print | OutDest::Inherit => Ok(Self::inherit()),
62            OutDest::File(file) => Ok(file.try_clone()?.into()),
63        }
64    }
65}