use std::sync::Arc;
use clap::Parser;
use wdotool::{Cli, DispatchCtx, ExitCode};
use wdotool_core::backend::mock::{BackendCall, MockBackend};
use wdotool_core::detector::Environment;
use wdotool_core::{Result as WdoResult, WdoError};
#[allow(dead_code)]
pub struct RunResult {
pub exit: ExitCode,
pub error: Option<WdoError>,
pub calls: Vec<BackendCall>,
pub stdout: String,
pub stderr: String,
}
pub async fn run(argv: &[&str]) -> RunResult {
run_with(argv, MockBackend::new(), Environment::default()).await
}
pub async fn run_with(argv: &[&str], mock: MockBackend, env: Environment) -> RunResult {
let mock = Arc::new(mock);
let argv_owned: Vec<String> = if argv.first().copied() == Some("wdotool") {
argv.iter().map(|s| s.to_string()).collect()
} else {
std::iter::once("wdotool".to_string())
.chain(argv.iter().map(|s| s.to_string()))
.collect()
};
let cli = match Cli::try_parse_from(&argv_owned) {
Ok(c) => c,
Err(e) => panic!("clap parse failed for {argv:?}: {e}"),
};
let mut stdout = Vec::<u8>::new();
let mut stderr = Vec::<u8>::new();
let outcome: WdoResult<ExitCode> = {
let mut ctx = DispatchCtx {
backend: &*mock,
env: &env,
stdout: &mut stdout,
stderr: &mut stderr,
};
wdotool::dispatch(&mut ctx, cli.command).await
};
let (exit, error) = match outcome {
Ok(code) => (code, None),
Err(e) => (ExitCode::FAILURE, Some(e)),
};
let calls = mock.calls();
RunResult {
exit,
error,
calls,
stdout: String::from_utf8(stdout).expect("stdout is not utf8"),
stderr: String::from_utf8(stderr).expect("stderr is not utf8"),
}
}