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}