lmrc_ssh/
output.rs

1//! Command output types.
2
3/// The output of an executed SSH command.
4///
5/// Contains the standard output, standard error, and exit status
6/// of the executed command.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct CommandOutput {
9    /// The standard output from the command.
10    pub stdout: String,
11
12    /// The standard error from the command.
13    pub stderr: String,
14
15    /// The exit status code of the command.
16    /// 0 typically indicates success, while non-zero indicates an error.
17    pub exit_status: i32,
18}
19
20impl CommandOutput {
21    /// Creates a new `CommandOutput` instance.
22    ///
23    /// # Arguments
24    ///
25    /// * `stdout` - The standard output from the command
26    /// * `stderr` - The standard error from the command
27    /// * `exit_status` - The exit status code
28    ///
29    /// # Examples
30    ///
31    /// ```
32    /// use lmrc_ssh::CommandOutput;
33    ///
34    /// let output = CommandOutput::new(
35    ///     "Hello, World!".to_string(),
36    ///     String::new(),
37    ///     0
38    /// );
39    /// assert_eq!(output.stdout, "Hello, World!");
40    /// assert!(output.is_success());
41    /// ```
42    pub fn new(stdout: String, stderr: String, exit_status: i32) -> Self {
43        Self {
44            stdout,
45            stderr,
46            exit_status,
47        }
48    }
49
50    /// Returns `true` if the command executed successfully (exit status 0).
51    ///
52    /// # Examples
53    ///
54    /// ```
55    /// use lmrc_ssh::CommandOutput;
56    ///
57    /// let success = CommandOutput::new("output".to_string(), String::new(), 0);
58    /// assert!(success.is_success());
59    ///
60    /// let failure = CommandOutput::new(String::new(), "error".to_string(), 1);
61    /// assert!(!failure.is_success());
62    /// ```
63    pub fn is_success(&self) -> bool {
64        self.exit_status == 0
65    }
66
67    /// Returns `true` if the command failed (non-zero exit status).
68    ///
69    /// # Examples
70    ///
71    /// ```
72    /// use lmrc_ssh::CommandOutput;
73    ///
74    /// let output = CommandOutput::new(String::new(), "error".to_string(), 1);
75    /// assert!(output.is_failure());
76    /// ```
77    pub fn is_failure(&self) -> bool {
78        !self.is_success()
79    }
80
81    /// Returns the combined output (stdout + stderr).
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// use lmrc_ssh::CommandOutput;
87    ///
88    /// let output = CommandOutput::new(
89    ///     "line1\n".to_string(),
90    ///     "error1\n".to_string(),
91    ///     0
92    /// );
93    /// assert_eq!(output.combined_output(), "line1\nerror1\n");
94    /// ```
95    pub fn combined_output(&self) -> String {
96        format!("{}{}", self.stdout, self.stderr)
97    }
98}
99
100impl std::fmt::Display for CommandOutput {
101    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102        write!(
103            f,
104            "Exit Status: {}\nStdout:\n{}\nStderr:\n{}",
105            self.exit_status, self.stdout, self.stderr
106        )
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn test_new_output() {
116        let output = CommandOutput::new("test".to_string(), "err".to_string(), 0);
117        assert_eq!(output.stdout, "test");
118        assert_eq!(output.stderr, "err");
119        assert_eq!(output.exit_status, 0);
120    }
121
122    #[test]
123    fn test_is_success() {
124        let success = CommandOutput::new(String::new(), String::new(), 0);
125        assert!(success.is_success());
126        assert!(!success.is_failure());
127
128        let failure = CommandOutput::new(String::new(), String::new(), 1);
129        assert!(failure.is_failure());
130        assert!(!failure.is_success());
131    }
132
133    #[test]
134    fn test_combined_output() {
135        let output = CommandOutput::new("out\n".to_string(), "err\n".to_string(), 0);
136        assert_eq!(output.combined_output(), "out\nerr\n");
137    }
138
139    #[test]
140    fn test_display() {
141        let output = CommandOutput::new("stdout".to_string(), "stderr".to_string(), 0);
142        let display = format!("{}", output);
143        assert!(display.contains("Exit Status: 0"));
144        assert!(display.contains("stdout"));
145        assert!(display.contains("stderr"));
146    }
147}