use std::{error::Error, process::ExitCode};
use crate::ArgError;
pub fn find_argerror<'a>(mut err: &'a (dyn Error + 'static)) -> Option<&'a ArgError> {
loop {
let x = err.downcast_ref::<ArgError>();
match x {
Some(a) => return Some(a),
None => match err.source() {
None => return None,
Some(e) => err = e,
},
}
}
}
pub fn report_argerror(usage: &str, argerr: &ArgError) -> ExitCode {
match argerr {
ArgError::ExitSuccessfully => ExitCode::SUCCESS,
ArgError::InvalidUnicode(_) => {
eprintln!("Error: {}", argerr);
ExitCode::FAILURE
}
_ => {
eprintln!("Error: {}", argerr);
eprintln!("{}", usage.trim());
ExitCode::FAILURE
}
}
}
#[allow(unused)]
pub fn report_errors<E>(usage: &str, result: Result<(), E>) -> ExitCode
where
E: AsRef<dyn Error + 'static>,
{
let error = match result {
Ok(t) => return ExitCode::SUCCESS,
Err(e) => e,
};
let e = error.as_ref();
if let Some(ae) = find_argerror(e) {
return report_argerror(usage, ae);
}
let mut cur: &dyn Error = e;
eprintln!("Error: {}", cur);
while let Some(e) = cur.source() {
eprintln!("caused by:");
eprintln!(" {}", e);
cur = e;
}
ExitCode::FAILURE
}