mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-22 13:38:43 +00:00
60 lines
1.6 KiB
Rust
60 lines
1.6 KiB
Rust
use std::{
|
|
future::Future,
|
|
process::{ExitCode, Termination},
|
|
time::Duration,
|
|
};
|
|
|
|
use binstalk::errors::BinstallError;
|
|
use binstalk::helpers::{signal::cancel_on_user_sig_term, tasks::AutoAbortJoinHandle};
|
|
use log::{error, info};
|
|
use miette::Result;
|
|
use tokio::runtime::Runtime;
|
|
|
|
pub enum MainExit {
|
|
Success(Duration),
|
|
Error(BinstallError),
|
|
Report(miette::Report),
|
|
}
|
|
|
|
impl Termination for MainExit {
|
|
fn report(self) -> ExitCode {
|
|
match self {
|
|
Self::Success(spent) => {
|
|
info!("Done in {spent:?}");
|
|
ExitCode::SUCCESS
|
|
}
|
|
Self::Error(err) => err.report(),
|
|
Self::Report(err) => {
|
|
error!("Fatal error:\n{err:?}");
|
|
ExitCode::from(16)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl MainExit {
|
|
pub fn new(result: Result<Result<()>, BinstallError>, done: Duration) -> Self {
|
|
result.map_or_else(MainExit::Error, |res| {
|
|
res.map(|()| MainExit::Success(done)).unwrap_or_else(|err| {
|
|
err.downcast::<BinstallError>()
|
|
.map(MainExit::Error)
|
|
.unwrap_or_else(MainExit::Report)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
/// This function would start a tokio multithreading runtime,
|
|
/// spawn a new task on it that runs `f`, then `block_on` it.
|
|
///
|
|
/// It will cancel the future if user requested cancellation
|
|
/// via signal.
|
|
pub fn run_tokio_main<F, T>(f: F) -> Result<T, BinstallError>
|
|
where
|
|
F: Future<Output = T> + Send + 'static,
|
|
T: Send + 'static,
|
|
{
|
|
let rt = Runtime::new()?;
|
|
let handle = AutoAbortJoinHandle::new(rt.spawn(f));
|
|
rt.block_on(cancel_on_user_sig_term(handle))
|
|
}
|