rmp_ipc/events/
event_handler.rs

1use crate::error::Result;
2use crate::events::event::Event;
3use crate::ipc::context::Context;
4use std::collections::HashMap;
5use std::fmt::{Debug, Formatter};
6use std::future::Future;
7use std::pin::Pin;
8use std::sync::Arc;
9
10type EventCallback = Arc<
11    dyn for<'a> Fn(&'a Context, Event) -> Pin<Box<(dyn Future<Output = Result<()>> + Send + 'a)>>
12        + Send
13        + Sync,
14>;
15
16/// Handler for events
17#[derive(Clone)]
18pub struct EventHandler {
19    callbacks: HashMap<String, EventCallback>,
20}
21
22impl Debug for EventHandler {
23    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
24        let callback_names: String = self
25            .callbacks
26            .keys()
27            .cloned()
28            .collect::<Vec<String>>()
29            .join(", ");
30        format!("EventHandler {{callbacks: [{}]}}", callback_names).fmt(f)
31    }
32}
33
34impl EventHandler {
35    /// Creates a new event handler
36    pub fn new() -> Self {
37        Self {
38            callbacks: HashMap::new(),
39        }
40    }
41
42    /// Adds a new event callback
43    #[tracing::instrument(skip(self, callback))]
44    pub fn on<F: 'static>(&mut self, name: &str, callback: F)
45    where
46        F: for<'a> Fn(
47                &'a Context,
48                Event,
49            ) -> Pin<Box<(dyn Future<Output = Result<()>> + Send + 'a)>>
50            + Send
51            + Sync,
52    {
53        self.callbacks.insert(name.to_string(), Arc::new(callback));
54    }
55
56    /// Handles a received event
57    #[tracing::instrument(level = "debug", skip(self, ctx, event))]
58    pub async fn handle_event(&self, ctx: &Context, event: Event) -> Result<()> {
59        if let Some(cb) = self.callbacks.get(event.name()) {
60            cb.as_ref()(ctx, event).await?;
61        }
62
63        Ok(())
64    }
65}