use std::path::PathBuf;
use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum OutputMode {
Separate,
Combined,
}
#[derive(Debug)]
pub struct CapturedOutput {
dir: tempfile::TempDir,
mode: OutputMode,
}
impl CapturedOutput {
pub fn new(mode: OutputMode) -> std::io::Result<Self> {
Ok(Self {
dir: tempfile::TempDir::with_prefix("synwire-")?,
mode,
})
}
#[must_use]
pub fn stdout_path(&self) -> PathBuf {
match self.mode {
OutputMode::Combined => self.dir.path().join("output"),
OutputMode::Separate => self.dir.path().join("stdout"),
}
}
#[must_use]
pub fn stderr_path(&self) -> Option<PathBuf> {
match self.mode {
OutputMode::Separate => Some(self.dir.path().join("stderr")),
OutputMode::Combined => None,
}
}
pub fn read_stdout(&self) -> std::io::Result<String> {
let path = self.stdout_path();
if path.exists() {
std::fs::read_to_string(path)
} else {
Ok(String::new())
}
}
pub fn read_stderr(&self) -> std::io::Result<Option<String>> {
match self.stderr_path() {
Some(p) if p.exists() => std::fs::read_to_string(p).map(Some),
Some(_) => Ok(Some(String::new())),
None => Ok(None),
}
}
#[must_use]
pub const fn mode(&self) -> OutputMode {
self.mode
}
}
#[derive(Debug)]
pub struct ProcessCapture {
pub output: Arc<CapturedOutput>,
pub child: tokio::process::Child,
pub(crate) _bundle: Option<tempfile::TempDir>,
}