use bytes::Bytes;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LogOutput {
StdOut {
message: Bytes,
},
StdErr {
message: Bytes,
},
StdIn {
message: Bytes,
},
Console {
message: Bytes,
},
}
impl LogOutput {
pub fn as_bytes(&self) -> &[u8] {
match self {
LogOutput::StdOut { message } => message.as_ref(),
LogOutput::StdErr { message } => message.as_ref(),
LogOutput::StdIn { message } => message.as_ref(),
LogOutput::Console { message } => message.as_ref(),
}
}
pub fn as_str_lossy(&self) -> std::borrow::Cow<'_, str> {
String::from_utf8_lossy(self.as_bytes())
}
pub fn is_stdout(&self) -> bool {
matches!(self, LogOutput::StdOut { .. })
}
pub fn is_stderr(&self) -> bool {
matches!(self, LogOutput::StdErr { .. })
}
pub fn is_stdin(&self) -> bool {
matches!(self, LogOutput::StdIn { .. })
}
pub fn is_console(&self) -> bool {
matches!(self, LogOutput::Console { .. })
}
}
impl From<bollard::container::LogOutput> for LogOutput {
fn from(output: bollard::container::LogOutput) -> Self {
match output {
bollard::container::LogOutput::StdOut { message } => LogOutput::StdOut { message },
bollard::container::LogOutput::StdErr { message } => LogOutput::StdErr { message },
bollard::container::LogOutput::StdIn { message } => LogOutput::StdIn { message },
bollard::container::LogOutput::Console { message } => LogOutput::Console { message },
}
}
}
impl std::fmt::Display for LogOutput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str_lossy())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_log_output_stdout() {
let output = LogOutput::StdOut {
message: Bytes::from("test message\n"),
};
assert!(output.is_stdout());
assert!(!output.is_stderr());
assert!(!output.is_stdin());
assert!(!output.is_console());
assert_eq!(output.as_bytes(), b"test message\n");
assert_eq!(output.as_str_lossy(), "test message\n");
}
#[test]
fn test_log_output_stderr() {
let output = LogOutput::StdErr {
message: Bytes::from("error message\n"),
};
assert!(!output.is_stdout());
assert!(output.is_stderr());
assert!(!output.is_stdin());
assert!(!output.is_console());
assert_eq!(output.as_bytes(), b"error message\n");
assert_eq!(output.as_str_lossy(), "error message\n");
}
#[test]
fn test_log_output_stdin() {
let output = LogOutput::StdIn {
message: Bytes::from("input message\n"),
};
assert!(!output.is_stdout());
assert!(!output.is_stderr());
assert!(output.is_stdin());
assert!(!output.is_console());
}
#[test]
fn test_log_output_console() {
let output = LogOutput::Console {
message: Bytes::from("console message\n"),
};
assert!(!output.is_stdout());
assert!(!output.is_stderr());
assert!(!output.is_stdin());
assert!(output.is_console());
}
#[test]
fn test_log_output_display() {
let output = LogOutput::StdOut {
message: Bytes::from("display test\n"),
};
assert_eq!(format!("{}", output), "display test\n");
}
#[test]
fn test_log_output_from_bollard() {
let bollard_output = bollard::container::LogOutput::StdOut {
message: Bytes::from("test\n"),
};
let output: LogOutput = bollard_output.into();
assert!(output.is_stdout());
assert_eq!(output.as_str_lossy(), "test\n");
}
#[test]
fn test_log_output_lossy_conversion() {
let invalid_utf8 = vec![0xFF, 0xFE, 0xFD];
let output = LogOutput::StdOut {
message: Bytes::from(invalid_utf8),
};
let lossy = output.as_str_lossy();
assert!(!lossy.is_empty());
}
}