1use anyhow::Result;
2use async_trait::async_trait;
3use std::collections::HashMap;
4use std::sync::Arc;
5use tokio::sync::Mutex;
6
7#[async_trait]
8pub trait EventHandler<T>: Send + Sync {
9 async fn handle(&self, payload: T) -> Result<()>;
10}
11
12#[async_trait]
13impl<T, F, Fut> EventHandler<T> for F
14where
15 T: Send + 'static,
16 F: Fn(T) -> Fut + Send + Sync,
17 Fut: std::future::Future<Output = Result<()>> + Send,
18{
19 async fn handle(&self, payload: T) -> Result<()> {
20 (self)(payload).await
21 }
22}
23
24pub struct EventEmitter<T> {
25 handlers: Arc<Mutex<HashMap<String, Vec<Box<dyn EventHandler<T>>>>>>,
26}
27
28impl<T: Clone + Send + 'static> EventEmitter<T> {
29 pub fn new() -> Self {
30 Self {
31 handlers: Arc::new(Mutex::new(HashMap::new())),
32 }
33 }
34
35 pub async fn on(&self, event: &str, handler: impl EventHandler<T> + 'static) {
36 let mut handlers = self.handlers.lock().await;
37 handlers
38 .entry(event.to_string())
39 .or_default()
40 .push(Box::new(handler));
41 }
42
43 pub async fn emit(&self, event: &str, payload: T) -> Result<()> {
44 let handlers = self.handlers.lock().await;
45 if let Some(list) = handlers.get(event) {
46 for handler in list {
47 handler.handle(payload.clone()).await?;
48 }
49 }
50 Ok(())
51 }
52}