use std::sync::atomic::{AtomicBool, Ordering};

static NEVER: AtomicBool = AtomicBool::new(false);

pub trait Cancel {
    fn is_canceled(&self) -> bool;
}

impl Cancel for AtomicBool {
    fn is_canceled(&self) -> bool {
        self.load(Ordering::Relaxed)
    }
}

#[derive(Copy, Clone)]
pub struct CancelFlag<'a>(&'a (dyn Cancel + Sync));

impl<'a> CancelFlag<'a> {
    #[must_use]
    pub fn new(source: &'a (dyn Cancel + Sync)) -> Self {
        Self(source)
    }

    #[must_use]
    pub fn is_canceled(self) -> bool {
        self.0.is_canceled()
    }
}

impl CancelFlag<'static> {
    #[must_use]
    pub fn never() -> Self {
        Self(&NEVER)
    }
}
