atlas_local/models/
log_output.rs1use bytes::Bytes;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum LogOutput {
41 StdOut {
43 message: Bytes,
45 },
46 StdErr {
48 message: Bytes,
50 },
51 StdIn {
53 message: Bytes,
55 },
56 Console {
58 message: Bytes,
60 },
61}
62
63impl LogOutput {
64 pub fn as_bytes(&self) -> &[u8] {
66 match self {
67 LogOutput::StdOut { message } => message.as_ref(),
68 LogOutput::StdErr { message } => message.as_ref(),
69 LogOutput::StdIn { message } => message.as_ref(),
70 LogOutput::Console { message } => message.as_ref(),
71 }
72 }
73
74 pub fn as_str_lossy(&self) -> std::borrow::Cow<'_, str> {
76 String::from_utf8_lossy(self.as_bytes())
77 }
78
79 pub fn is_stdout(&self) -> bool {
81 matches!(self, LogOutput::StdOut { .. })
82 }
83
84 pub fn is_stderr(&self) -> bool {
86 matches!(self, LogOutput::StdErr { .. })
87 }
88
89 pub fn is_stdin(&self) -> bool {
91 matches!(self, LogOutput::StdIn { .. })
92 }
93
94 pub fn is_console(&self) -> bool {
96 matches!(self, LogOutput::Console { .. })
97 }
98}
99
100impl From<bollard::container::LogOutput> for LogOutput {
101 fn from(output: bollard::container::LogOutput) -> Self {
102 match output {
103 bollard::container::LogOutput::StdOut { message } => LogOutput::StdOut { message },
104 bollard::container::LogOutput::StdErr { message } => LogOutput::StdErr { message },
105 bollard::container::LogOutput::StdIn { message } => LogOutput::StdIn { message },
106 bollard::container::LogOutput::Console { message } => LogOutput::Console { message },
107 }
108 }
109}
110
111impl std::fmt::Display for LogOutput {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 write!(f, "{}", self.as_str_lossy())
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_log_output_stdout() {
123 let output = LogOutput::StdOut {
124 message: Bytes::from("test message\n"),
125 };
126
127 assert!(output.is_stdout());
128 assert!(!output.is_stderr());
129 assert!(!output.is_stdin());
130 assert!(!output.is_console());
131 assert_eq!(output.as_bytes(), b"test message\n");
132 assert_eq!(output.as_str_lossy(), "test message\n");
133 }
134
135 #[test]
136 fn test_log_output_stderr() {
137 let output = LogOutput::StdErr {
138 message: Bytes::from("error message\n"),
139 };
140
141 assert!(!output.is_stdout());
142 assert!(output.is_stderr());
143 assert!(!output.is_stdin());
144 assert!(!output.is_console());
145 assert_eq!(output.as_bytes(), b"error message\n");
146 assert_eq!(output.as_str_lossy(), "error message\n");
147 }
148
149 #[test]
150 fn test_log_output_stdin() {
151 let output = LogOutput::StdIn {
152 message: Bytes::from("input message\n"),
153 };
154
155 assert!(!output.is_stdout());
156 assert!(!output.is_stderr());
157 assert!(output.is_stdin());
158 assert!(!output.is_console());
159 }
160
161 #[test]
162 fn test_log_output_console() {
163 let output = LogOutput::Console {
164 message: Bytes::from("console message\n"),
165 };
166
167 assert!(!output.is_stdout());
168 assert!(!output.is_stderr());
169 assert!(!output.is_stdin());
170 assert!(output.is_console());
171 }
172
173 #[test]
174 fn test_log_output_display() {
175 let output = LogOutput::StdOut {
176 message: Bytes::from("display test\n"),
177 };
178
179 assert_eq!(format!("{}", output), "display test\n");
180 }
181
182 #[test]
183 fn test_log_output_from_bollard() {
184 let bollard_output = bollard::container::LogOutput::StdOut {
185 message: Bytes::from("test\n"),
186 };
187
188 let output: LogOutput = bollard_output.into();
189 assert!(output.is_stdout());
190 assert_eq!(output.as_str_lossy(), "test\n");
191 }
192
193 #[test]
194 fn test_log_output_lossy_conversion() {
195 let invalid_utf8 = vec![0xFF, 0xFE, 0xFD];
197 let output = LogOutput::StdOut {
198 message: Bytes::from(invalid_utf8),
199 };
200
201 let lossy = output.as_str_lossy();
203 assert!(!lossy.is_empty());
204 }
205}