use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
#[derive(Debug, Clone, Default)]
pub struct CancellationToken {
inner: Arc<AtomicBool>,
}
impl CancellationToken {
#[must_use]
pub fn new() -> Self {
Self {
inner: Arc::new(AtomicBool::new(false)),
}
}
pub fn cancel(&self) {
self.inner.store(true, Ordering::Release);
}
#[must_use]
pub fn is_cancelled(&self) -> bool {
self.inner.load(Ordering::Acquire)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_token_is_not_cancelled() {
assert!(!CancellationToken::new().is_cancelled());
}
#[test]
fn cancel_flips_for_all_clones() {
let a = CancellationToken::new();
let b = a.clone();
assert!(!a.is_cancelled());
assert!(!b.is_cancelled());
a.cancel();
assert!(a.is_cancelled());
assert!(b.is_cancelled());
}
#[test]
fn cancel_is_idempotent() {
let t = CancellationToken::new();
t.cancel();
t.cancel();
assert!(t.is_cancelled());
}
}