Skip to main content

kawauso_process/run/
stream.rs

1//! The stream of a command that produced a line of output
2
3use std::fmt::Display;
4use std::fmt::Formatter;
5use std::fmt::Result;
6
7/// The stream of a command that produced a line of output
8///
9/// A command writes its result to one stream and its diagnostics to another,
10/// and a reader of the output has to know which of the two it reads. A line
11/// carries this value, so that a caller can show a diagnostic apart from a
12/// result, or drop one of the two.
13///
14/// A command has these two output streams and no other, so a match on the
15/// value needs no arm for a stream that a later release adds.
16///
17/// # Examples
18///
19/// ```
20/// use kawauso_process::run::Stream;
21///
22/// assert_eq!(Stream::StandardError.to_string(), "standard error");
23/// ```
24#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
25pub enum Stream {
26    /// The stream on which a command states why it stopped
27    StandardError,
28
29    /// The stream on which a command writes its result
30    StandardOutput,
31}
32
33/// Names the stream for a reader
34///
35/// The name is the one that the documentation of an operating system uses, so
36/// that a log line names the stream that a reader looks for.
37impl Display for Stream {
38    fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
39        match self {
40            Self::StandardError => formatter.write_str("standard error"),
41            Self::StandardOutput => formatter.write_str("standard output"),
42        }
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    // An assertion in a test panics by design. A `# Panics` section on every
49    // test would repeat that and give the reader no information.
50    #![allow(clippy::missing_panics_doc)]
51
52    use super::*;
53
54    // A caller keeps a line in a report that another thread reads. This test
55    // holds the type to the auto traits that make this possible, because a
56    // private field of a later version could take them away without a word
57    // from the compiler.
58    #[test]
59    fn stream_is_send_and_sync() {
60        fn assert_send_and_sync<T: Send + Sync>() {}
61
62        assert_send_and_sync::<Stream>();
63    }
64
65    // A log line names the stream through `Display`, and the name of the
66    // standard error is the one that a reader of a manual knows.
67    #[test]
68    fn to_string_of_the_standard_error_names_the_stream() {
69        let stream = Stream::StandardError;
70
71        assert_eq!(stream.to_string(), "standard error");
72    }
73
74    // A log line names the stream through `Display`, and the name of the
75    // standard output is the one that a reader of a manual knows.
76    #[test]
77    fn to_string_of_the_standard_output_names_the_stream() {
78        let stream = Stream::StandardOutput;
79
80        assert_eq!(stream.to_string(), "standard output");
81    }
82}