Skip to main content

agentlib_utils/
lib.rs

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}