use anyhow::{bail, Context, Result};
use std::env;
use std::path::PathBuf;
use std::process::{Command, ExitCode};
use trust_rustc::{find_input_rs, prepare_strict_input};
fn main() -> ExitCode {
match run() {
Ok(code) => ExitCode::from(u8::try_from(code & 0xff).unwrap_or(1)),
Err(e) => {
eprintln!("trust-rustc: {e:#}");
ExitCode::FAILURE
}
}
}
fn run() -> Result<i32> {
let argv: Vec<String> = env::args().skip(1).collect();
if argv.is_empty() {
bail!("usage: trust-rustc <real-rustc-path> [rustc-args...]");
}
let rustc = &argv[0];
let rustc_args: Vec<String> = argv[1..].to_vec();
let Some(idx) = find_input_rs(&rustc_args) else {
return run_rustc(rustc, &rustc_args);
};
let Some(input_arg) = rustc_args.get(idx) else {
return run_rustc(rustc, &rustc_args);
};
let input_path = PathBuf::from(input_arg);
let Some(prepared) = prepare_strict_input(&input_path)
.with_context(|| format!("preparing {}", input_path.display()))?
else {
return run_rustc(rustc, &rustc_args);
};
let mut new_args = rustc_args.clone();
if let Some(slot) = new_args.get_mut(idx) {
*slot = prepared.lowered_root.to_string_lossy().into_owned();
}
new_args.push(prepared.remap_flag);
run_rustc(rustc, &new_args)
}
fn run_rustc(path: &str, args: &[String]) -> Result<i32> {
let status = Command::new(path)
.args(args)
.status()
.with_context(|| format!("invoking {path}"))?;
Ok(status.code().unwrap_or(1))
}