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}