torrust_tracker_deployer_lib/shared/command/
result.rs1use std::process::ExitStatus;
7
8#[derive(Debug, Clone)]
13pub struct CommandResult {
14 pub exit_status: ExitStatus,
16
17 pub stdout: String,
19
20 pub stderr: String,
22}
23
24impl CommandResult {
25 #[must_use]
27 pub fn new(exit_status: ExitStatus, stdout: String, stderr: String) -> Self {
28 Self {
29 exit_status,
30 stdout,
31 stderr,
32 }
33 }
34
35 #[must_use]
37 pub fn is_success(&self) -> bool {
38 self.exit_status.success()
39 }
40
41 #[must_use]
43 pub fn exit_code(&self) -> Option<i32> {
44 self.exit_status.code()
45 }
46
47 #[must_use]
49 pub fn stdout_trimmed(&self) -> &str {
50 self.stdout.trim()
51 }
52
53 #[must_use]
55 pub fn stderr_trimmed(&self) -> &str {
56 self.stderr.trim()
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use std::process::{Command, Stdio};
64
65 #[test]
66 fn it_should_provide_complete_command_result_information() {
67 let output = Command::new("echo")
69 .arg("test")
70 .stdout(Stdio::piped())
71 .stderr(Stdio::piped())
72 .output()
73 .expect("Failed to execute echo command");
74
75 let command_result = CommandResult::new(
76 output.status,
77 String::from_utf8_lossy(&output.stdout).to_string(),
78 String::from_utf8_lossy(&output.stderr).to_string(),
79 );
80
81 assert!(command_result.is_success());
83 assert_eq!(command_result.exit_code(), Some(0));
84 assert_eq!(command_result.stdout_trimmed(), "test");
85 assert_eq!(command_result.stderr_trimmed(), "");
86
87 assert!(command_result.stdout.contains("test"));
89 assert!(command_result.stderr.is_empty());
90 }
91
92 #[test]
93 fn it_should_handle_command_with_stderr() {
94 let output = Command::new("ls")
96 .arg("/nonexistent_directory_xyz123")
97 .stdout(Stdio::piped())
98 .stderr(Stdio::piped())
99 .output()
100 .expect("Failed to execute ls command");
101
102 let command_result = CommandResult::new(
103 output.status,
104 String::from_utf8_lossy(&output.stdout).to_string(),
105 String::from_utf8_lossy(&output.stderr).to_string(),
106 );
107
108 assert!(!command_result.is_success());
110 assert!(command_result.exit_code().is_some());
111 assert_ne!(command_result.exit_code(), Some(0));
112
113 assert!(!command_result.stderr_trimmed().is_empty());
115 }
116
117 #[test]
118 fn it_should_trim_whitespace_correctly() {
119 let output = Command::new("echo")
121 .arg(" spaced ")
122 .stdout(Stdio::piped())
123 .stderr(Stdio::piped())
124 .output()
125 .expect("Failed to execute echo command");
126
127 let command_result = CommandResult::new(
128 output.status,
129 String::from_utf8_lossy(&output.stdout).to_string(),
130 String::from_utf8_lossy(&output.stderr).to_string(),
131 );
132
133 assert_eq!(command_result.stdout_trimmed(), "spaced");
135 assert!(command_result.stdout.contains(" spaced "));
137 }
138}