use std::{io, ops, process::{Child, Command, Stdio}};
use clap::Parser;
use energy_bench::{EnergyBench, EnergyBenchConfig};
#[derive(Parser)]
struct Args {
#[arg(long)]
name: String,
#[command(flatten)]
config: EnergyBenchConfig,
#[arg(trailing_var_arg = true)]
args: Vec<String>,
}
struct Guard(Child);
impl ops::Deref for Guard {
type Target = Child;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl ops::DerefMut for Guard {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Drop for Guard {
fn drop(&mut self) {
let _ = self.0.kill();
let _ = self.0.wait();
}
}
fn run(prog: &String, args: &[String]) -> io::Result<()> {
let mut cmd = Command::new(prog);
cmd.args(args).stdout(Stdio::null()).stderr(Stdio::null());
Guard(cmd.spawn()?).wait()?;
Ok(())
}
fn main() {
env_logger::init();
let Args {
name,
config,
args,
} = Args::parse();
let (prog, args) = (&args).split_first().expect("no command provided");
let mut bench = EnergyBench::new(&name, config);
bench.benchmark(prog, || run(prog, args));
}