use std::fmt;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct CancellationToken {
is_cancelled: Arc<AtomicBool>,
}
impl Default for CancellationToken {
fn default() -> Self {
Self::new()
}
}
impl CancellationToken {
pub fn new() -> Self {
Self {
is_cancelled: Arc::new(AtomicBool::new(false)),
}
}
pub fn cancel(&self) {
self.is_cancelled.store(true, Ordering::SeqCst);
}
pub fn is_cancelled(&self) -> bool {
self.is_cancelled.load(Ordering::SeqCst)
}
pub fn check_cancelled(&self) -> Result<(), CancellationError> {
if self.is_cancelled() {
Err(CancellationError::Cancelled)
} else {
Ok(())
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CancellationError {
Cancelled,
}
impl fmt::Display for CancellationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CancellationError::Cancelled => write!(f, "Operation cancelled"),
}
}
}
impl std::error::Error for CancellationError {}
pub type CancellationResult<T> = Result<T, CancellationError>;