use std::io::Read; use std::io::Write; pub fn main() -> ! { let exit_code = run_main(); std::process::exit(exit_code); } /// We would prefer to return `std::process::ExitCode`, but its `exit_process()` /// method is still a nightly API and we want main() to return !. pub fn run_main() -> i32 { // Expect either one argument (the full apply_patch payload) or read it from stdin. let mut args = std::env::args_os(); let _argv0 = args.next(); let patch_arg = match args.next() { Some(arg) => match arg.into_string() { Ok(s) => s, Err(_) => { eprintln!("Error: apply_patch requires a UTF-8 PATCH argument."); return 1; } }, None => { // No argument provided; attempt to read the patch from stdin. let mut buf = String::new(); match std::io::stdin().read_to_string(&mut buf) { Ok(_) => { if buf.is_empty() { eprintln!("Usage: apply_patch 'PATCH'\n echo 'PATCH' | apply-patch"); return 2; } buf } Err(err) => { eprintln!("Error: Failed to read PATCH from stdin.\n{err}"); return 1; } } } }; // Refuse extra args to avoid ambiguity. if args.next().is_some() { eprintln!("Error: apply_patch accepts exactly one argument."); return 2; } let mut stdout = std::io::stdout(); let mut stderr = std::io::stderr(); match crate::apply_patch(&patch_arg, &mut stdout, &mut stderr) { Ok(()) => { // Flush to ensure output ordering when used in pipelines. let _ = stdout.flush(); 0 } Err(_) => 1, } }