Use new Termination trait

This commit is contained in:
Félix Saparelli 2022-05-31 22:15:20 +12:00
parent f56ed6fc4c
commit bd35c473a9
No known key found for this signature in database
GPG key ID: B948C4BAE44FC474
2 changed files with 51 additions and 21 deletions

View file

@ -1,3 +1,6 @@
use std::process::{ExitCode, Termination};
use log::warn;
use miette::Diagnostic; use miette::Diagnostic;
use thiserror::Error; use thiserror::Error;
@ -152,9 +155,9 @@ impl BinstallError {
/// - 1 and 2 (catchall and shell) /// - 1 and 2 (catchall and shell)
/// - 16 (binstall errors not handled here) /// - 16 (binstall errors not handled here)
/// - 64 (generic error) /// - 64 (generic error)
pub fn exit_code(&self) -> u8 { pub fn exit_code(&self) -> ExitCode {
use BinstallError::*; use BinstallError::*;
let code = match self { let code: u8 = match self {
UserAbort => 32, UserAbort => 32,
UrlParse(_) => 65, UrlParse(_) => 65,
Unzip(_) => 66, Unzip(_) => 66,
@ -173,6 +176,18 @@ impl BinstallError {
// reserved codes // reserved codes
debug_assert!(code != 64 && code != 16 && code != 1 && code != 2 && code != 0); debug_assert!(code != 64 && code != 16 && code != 1 && code != 2 && code != 0);
code code.into()
}
}
impl Termination for BinstallError {
fn report(self) -> ExitCode {
if let BinstallError::UserAbort = self {
warn!("Installation cancelled");
} else {
eprintln!("{self:?}");
}
self.exit_code()
} }
} }

View file

@ -1,4 +1,9 @@
use std::{path::PathBuf, process::exit, str::FromStr, time::Instant}; use std::{
path::PathBuf,
process::{ExitCode, Termination},
str::FromStr,
time::{Duration, Instant},
};
use cargo_toml::{Package, Product}; use cargo_toml::{Package, Product};
use log::{debug, error, info, warn, LevelFilter}; use log::{debug, error, info, warn, LevelFilter};
@ -75,7 +80,29 @@ struct Options {
pkg_url: Option<String>, pkg_url: Option<String>,
} }
fn main() -> ! { enum MainExit {
Success(Duration),
Error(BinstallError),
Report(miette::Report),
}
impl Termination for MainExit {
fn report(self) -> ExitCode {
match self {
Self::Success(spent) => {
info!("Installation complete! [{spent:?}]");
ExitCode::SUCCESS
}
Self::Error(err) => err.report(),
Self::Report(err) => {
eprintln!("{err:?}");
ExitCode::from(16)
}
}
}
}
fn main() -> MainExit {
let start = Instant::now(); let start = Instant::now();
let rt = Runtime::new().unwrap(); let rt = Runtime::new().unwrap();
@ -83,27 +110,15 @@ fn main() -> ! {
drop(rt); drop(rt);
let done = start.elapsed(); let done = start.elapsed();
debug!("run time: {done:?}");
if let Err(err) = result { if let Err(err) = result {
debug!("run time: {done:?}");
match err.downcast::<BinstallError>() { match err.downcast::<BinstallError>() {
Ok(liberr @ BinstallError::UserAbort) => { Ok(liberr) => MainExit::Error(liberr),
warn!("Installation cancelled"); Err(binerr) => MainExit::Report(binerr),
exit(liberr.exit_code() as _);
}
Ok(liberr) => {
eprintln!("{liberr:?}");
exit(liberr.exit_code() as _);
}
Err(binerr) => {
eprintln!("{binerr:?}");
exit(16);
}
} }
} else { } else {
info!("Installation complete! [{done:?}]"); MainExit::Success(done)
exit(0);
} }
} }