tokens/
token.rs

1use std::{any::Any, sync::Arc, ops::Deref};
2
3pub type Callback = Box<dyn Fn(Option<Arc<dyn Any>>) + Send + Sync>;
4type CallbackRef = Arc<dyn Fn(Option<Arc<dyn Any>>) + Send + Sync>;
5
6/// Represents a [`ChangeToken`](crate::ChangeToken) registration.
7///
8/// # Remarks
9///
10/// When the registration is dropped, the underlying callback is unregistered.
11pub struct Registration(CallbackRef);
12
13impl Registration {
14    /// Initializes a new change token registration.
15    pub fn new(callback: CallbackRef) -> Self {
16        Self(callback)
17    }
18
19    /// Initializes a new, empty change token registration.
20    pub fn none() -> Self {
21        Self::default()
22    }
23}
24
25impl Default for Registration {
26    fn default() -> Self {
27        Self(Arc::new(|_| {}))
28    }
29}
30
31/// Propagates notifications that a change has occurred.
32pub trait ChangeToken: Send + Sync {
33    /// Gets a value that indicates if a change has occurred.
34    fn changed(&self) -> bool;
35
36    /// Indicates if this token will proactively raise callbacks.
37    ///
38    /// # Remarks
39    ///
40    /// If `false`, the token consumer should expect for that any callback
41    /// specified in [`register`](ChangeToken::register) will be invoked
42    /// when a change occurs. If `false`, the token consumer must poll
43    /// [`changed`](ChangeToken::changed) to detect changes.
44    fn must_poll(&self) -> bool {
45        false
46    }
47
48    /// Registers for a callback that will be invoked when the token has changed.
49    ///
50    /// # Arguments
51    ///
52    /// * `callback` - The callback to invoke
53    /// * `state` - The optional state provided to the callback, if any
54    /// 
55    /// # Returns
56    /// 
57    /// An opaque change token [registration](Registration). When it
58    /// is dropped, the callback function is unregistered.
59    fn register(&self, callback: Callback, state: Option<Arc<dyn Any>>) -> Registration;
60}
61
62// this allows Box<dyn ChangeToken> to be used for T: ChangeToken
63impl ChangeToken for Box<dyn ChangeToken> {
64    fn changed(&self) -> bool {
65        self.deref().changed()
66    }
67    
68    fn must_poll(&self) -> bool {
69        self.deref().must_poll()
70    }
71
72    fn register(&self, callback: Callback, state: Option<Arc<dyn Any>>) -> Registration {
73        self.deref().register(callback, state)
74    }
75}