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