Skip to main content

over_there/utils/
callback.rs

1use std::collections::HashMap;
2use std::fmt;
3use std::fmt::Debug;
4
5pub type Callback<T> = dyn FnOnce(&T) + Send;
6
7/// Synchronous manager of one-time callback functions
8/// that are allocated on the heap
9pub struct CallbackManager<T> {
10    /// Contains callback functions to invoke when a
11    /// response is received for a msg with a specific id
12    callbacks: HashMap<u32, Box<Callback<T>>>,
13}
14
15impl<T> CallbackManager<T> {
16    /// Adds a new callback, associated with the given id
17    pub fn add_callback(
18        &mut self,
19        id: u32,
20        callback: impl FnOnce(&T) + Send + 'static,
21    ) {
22        self.callbacks.insert(id, Box::new(callback));
23    }
24
25    /// Retrieves the callback with the associated id, but does not invoke it
26    pub fn take_callback(&mut self, id: u32) -> Option<Box<Callback<T>>> {
27        self.callbacks.remove(&id)
28    }
29
30    /// Retrieves and invokes the callback with the associated id
31    pub fn invoke_callback(&mut self, id: u32, input: &T) {
32        if let Some(callback) = self.take_callback(id) {
33            callback(input)
34        }
35    }
36}
37
38impl<T> Default for CallbackManager<T> {
39    fn default() -> Self {
40        Self {
41            callbacks: HashMap::default(),
42        }
43    }
44}
45
46impl<T> Debug for CallbackManager<T> {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        write!(
49            f,
50            "CallbackManager {{ callbacks: {:?} }}",
51            self.callbacks.keys(),
52        )
53    }
54}