use std::{fmt, io::Cursor, pin::Pin};
use tokio::io::{AsyncBufRead, AsyncReadExt};
use crate::core::error::Result;
pub struct ExecResult {
pub(crate) exit_code: Option<i64>,
pub(crate) stdout: Cursor<Vec<u8>>,
pub(crate) stderr: Cursor<Vec<u8>>,
}
impl ExecResult {
pub async fn exit_code(&self) -> Result<Option<i64>> {
Ok(self.exit_code)
}
pub fn stdout<'b>(&'b mut self) -> Pin<Box<dyn AsyncBufRead + Send + 'b>> {
Box::pin(&mut self.stdout)
}
pub fn stderr<'b>(&'b mut self) -> Pin<Box<dyn AsyncBufRead + Send + 'b>> {
Box::pin(&mut self.stderr)
}
pub async fn stdout_to_vec(&mut self) -> Result<Vec<u8>> {
let mut stdout = Vec::new();
self.stdout().read_to_end(&mut stdout).await?;
Ok(stdout)
}
pub async fn stderr_to_vec(&mut self) -> Result<Vec<u8>> {
let mut stderr = Vec::new();
self.stderr().read_to_end(&mut stderr).await?;
Ok(stderr)
}
}
impl fmt::Debug for ExecResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExecResult")
.field("exit_code", &self.exit_code)
.finish()
}
}