use std::process::{Output, Stdio};
use std::time::Duration;
use anyhow::{Context, Result, anyhow};
use tokio::process::Command;
use tokio::time;
pub enum RunOutcome {
Completed(Output),
TimedOut,
}
pub async fn run_with_timeout(
program: &str,
args: &[String],
timeout: Duration,
) -> Result<RunOutcome> {
let mut cmd = Command::new(program);
cmd.args(args)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped());
let child = cmd
.spawn()
.with_context(|| format!("Failed to spawn command: {} {:?}", program, args))?;
match time::timeout(timeout, child.wait_with_output()).await {
Ok(Ok(output)) => Ok(RunOutcome::Completed(output)),
Ok(Err(e)) => Err(anyhow!("Error while running command: {}", e)),
Err(_) => Ok(RunOutcome::TimedOut),
}
}