#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CommandOutput {
pub stdout: String,
pub stderr: String,
pub exit_status: i32,
}
impl CommandOutput {
pub fn new(stdout: String, stderr: String, exit_status: i32) -> Self {
Self {
stdout,
stderr,
exit_status,
}
}
pub fn is_success(&self) -> bool {
self.exit_status == 0
}
pub fn is_failure(&self) -> bool {
!self.is_success()
}
pub fn combined_output(&self) -> String {
format!("{}{}", self.stdout, self.stderr)
}
}
impl std::fmt::Display for CommandOutput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Exit Status: {}\nStdout:\n{}\nStderr:\n{}",
self.exit_status, self.stdout, self.stderr
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_output() {
let output = CommandOutput::new("test".to_string(), "err".to_string(), 0);
assert_eq!(output.stdout, "test");
assert_eq!(output.stderr, "err");
assert_eq!(output.exit_status, 0);
}
#[test]
fn test_is_success() {
let success = CommandOutput::new(String::new(), String::new(), 0);
assert!(success.is_success());
assert!(!success.is_failure());
let failure = CommandOutput::new(String::new(), String::new(), 1);
assert!(failure.is_failure());
assert!(!failure.is_success());
}
#[test]
fn test_combined_output() {
let output = CommandOutput::new("out\n".to_string(), "err\n".to_string(), 0);
assert_eq!(output.combined_output(), "out\nerr\n");
}
#[test]
fn test_display() {
let output = CommandOutput::new("stdout".to_string(), "stderr".to_string(), 0);
let display = format!("{}", output);
assert!(display.contains("Exit Status: 0"));
assert!(display.contains("stdout"));
assert!(display.contains("stderr"));
}
}