use crate::{Callback, ChangeToken, DefaultChangeToken, Registration, State};
pub struct SingleChangeToken(DefaultChangeToken);
impl SingleChangeToken {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn notify(&self) {
self.0.notify()
}
}
impl Default for SingleChangeToken {
#[inline]
fn default() -> Self {
Self(DefaultChangeToken::once())
}
}
impl ChangeToken for SingleChangeToken {
#[inline]
fn changed(&self) -> bool {
self.0.changed()
}
#[inline]
fn register(&self, callback: Callback, state: State) -> Registration {
self.0.register(callback, state)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::assert_send_and_sync;
use std::sync::{
atomic::{AtomicU8, Ordering::Relaxed},
Arc,
};
#[test]
fn single_change_token_should_send_and_sync() {
let token = SingleChangeToken::default();
assert_send_and_sync(token);
}
#[test]
fn single_change_token_should_be_unchanged() {
let token = SingleChangeToken::default();
let changed = token.changed();
assert_eq!(changed, false);
}
#[test]
fn single_change_token_should_be_changed() {
let token = SingleChangeToken::default();
token.notify();
assert_eq!(token.changed(), true);
}
#[test]
fn single_change_token_should_invoke_callback() {
let counter = Arc::new(AtomicU8::default());
let token = SingleChangeToken::default();
let _registration = token.register(
Box::new(|state| {
state.unwrap().downcast_ref::<AtomicU8>().unwrap().fetch_add(1, Relaxed);
}),
Some(counter.clone()),
);
token.notify();
assert_eq!(counter.load(Relaxed), 1);
}
#[test]
fn single_change_token_should_not_invoke_callback_more_than_once() {
let counter = Arc::new(AtomicU8::default());
let token = SingleChangeToken::default();
let _registration = token.register(
Box::new(|state| {
state.unwrap().downcast_ref::<AtomicU8>().unwrap().fetch_add(1, Relaxed);
}),
Some(counter.clone()),
);
token.notify();
token.notify();
assert_eq!(counter.load(Relaxed), 1);
}
}