use crate::{AsyncEvent, async_event::WaitAsyncEventFuture};
#[derive(Debug, Default)]
pub struct CancellationToken {
event: AsyncEvent,
}
impl CancellationToken {
pub fn new() -> Self {
let event = AsyncEvent::new();
Self { event }
}
pub fn is_cancelled(&self) -> bool {
self.event.is_set()
}
pub fn cancel(&self) {
self.event.set();
}
pub fn cancelled(&self) -> WaitAsyncEventFuture<'_> {
self.event.wait()
}
}
#[cfg(test)]
mod tests {
use std::rc::Rc;
use futures::select;
use super::*;
#[crate::test]
async fn test_cancellation_token() {
let token = CancellationToken::new();
assert!(!token.is_cancelled());
token.cancel();
assert!(token.is_cancelled());
let token = Rc::new(CancellationToken::new());
let task = {
let token = token.clone();
crate::operations::spawn_task(async move { token.cancel() })
};
assert!(!token.is_cancelled());
token.cancelled().await.unwrap();
assert!(token.is_cancelled());
task.await.unwrap();
}
#[crate::test]
async fn test_cancel_select() {
let token = CancellationToken::new();
let result = select! {
_ = token.cancelled() => "cancelled",
default => "not cancelled",
};
assert_eq!("not cancelled", result);
token.cancel();
let result = select! {
_ = token.cancelled() => "cancelled",
default => "not cancelled",
};
assert_eq!("cancelled", result);
}
}