use std::{
str,
time::Duration,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CommandOutput {
exit_code: Option<i32>,
stdout: Vec<u8>,
stderr: Vec<u8>,
elapsed: Duration,
stdout_text: Option<String>,
stderr_text: Option<String>,
}
impl CommandOutput {
#[inline]
pub(crate) fn new(
exit_code: Option<i32>,
stdout: Vec<u8>,
stderr: Vec<u8>,
elapsed: Duration,
lossy_output: bool,
) -> Self {
let stdout_text = if lossy_output {
Some(String::from_utf8_lossy(&stdout).into_owned())
} else {
None
};
let stderr_text = if lossy_output {
Some(String::from_utf8_lossy(&stderr).into_owned())
} else {
None
};
Self {
exit_code,
stdout,
stderr,
elapsed,
stdout_text,
stderr_text,
}
}
#[inline]
pub const fn exit_code(&self) -> Option<i32> {
self.exit_code
}
#[inline]
pub fn stdout(&self) -> Result<&str, str::Utf8Error> {
match &self.stdout_text {
Some(text) => Ok(text.as_str()),
None => str::from_utf8(&self.stdout),
}
}
#[inline]
pub fn stderr(&self) -> Result<&str, str::Utf8Error> {
match &self.stderr_text {
Some(text) => Ok(text.as_str()),
None => str::from_utf8(&self.stderr),
}
}
#[inline]
pub const fn elapsed(&self) -> Duration {
self.elapsed
}
#[inline]
pub fn stdout_bytes(&self) -> &[u8] {
&self.stdout
}
#[inline]
pub fn stderr_bytes(&self) -> &[u8] {
&self.stderr
}
}