use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
#[derive(Clone, Default)]
pub struct CancellationToken(Arc<AtomicBool>);
impl CancellationToken {
pub fn new() -> Self {
Self::default()
}
pub fn cancel(&self) {
self.0.store(true, Ordering::SeqCst);
}
pub fn is_cancelled(&self) -> bool {
self.0.load(Ordering::SeqCst)
}
}
impl std::fmt::Debug for CancellationToken {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CancellationToken")
.field("cancelled", &self.is_cancelled())
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn starts_uncancelled_and_is_shared_across_clones() {
let token = CancellationToken::new();
let clone = token.clone();
assert!(!token.is_cancelled());
assert!(!clone.is_cancelled());
clone.cancel();
assert!(token.is_cancelled());
assert!(clone.is_cancelled());
}
#[test]
fn independent_tokens_do_not_share_state() {
let a = CancellationToken::new();
let b = CancellationToken::new();
a.cancel();
assert!(a.is_cancelled());
assert!(!b.is_cancelled());
}
}