use anyhow::{Result, anyhow};
use std::fmt::{Display, Formatter};
use std::sync::atomic::AtomicBool;
use std::sync::{LazyLock, atomic};
static RUNNING_FLAG: LazyLock<AtomicBool> = LazyLock::new(|| AtomicBool::new(true));
pub fn is_running() -> bool {
RUNNING_FLAG.load(atomic::Ordering::Relaxed)
}
pub fn aborted() -> Result<()> {
match is_running() {
true => Ok(()),
false => Err(anyhow!("user asked to abort")),
}
}
pub fn display_abort(cond: bool) -> impl Display {
DisplayAbort { cond }
}
#[derive(Debug, Copy, Clone)]
pub struct DisplayAbort {
cond: bool,
}
impl Display for DisplayAbort {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if self.cond && !is_running() {
write!(f, " (aborted)")?;
}
Ok(())
}
}
pub fn install_ctrl_c_handler() {
let handler = || {
eprintln!(" aborting...");
RUNNING_FLAG.store(false, atomic::Ordering::Relaxed);
};
if let Err(err) = ctrlc::set_handler(handler) {
eprintln!("error: set Ctrl-C handler: {err:?}");
}
}