1use std::collections::HashMap;
5use std::sync::{Arc, RwLock};
6
7use futures::future::{join_all, BoxFuture};
8
9pub trait Listener: Send + Sync + 'static {
10 fn on_event(&self, payload: &serde_json::Value) -> BoxFuture<'static, ()>;
11}
12
13type Listeners = HashMap<&'static str, Vec<Arc<dyn Listener>>>;
14
15#[derive(Default, Clone)]
16pub struct EventBus {
17 inner: Arc<RwLock<Listeners>>,
18}
19
20impl EventBus {
21 pub fn new() -> Self {
22 Self::default()
23 }
24
25 pub fn subscribe(&self, event: &'static str, listener: Arc<dyn Listener>) {
26 self.inner
27 .write()
28 .unwrap()
29 .entry(event)
30 .or_default()
31 .push(listener);
32 }
33
34 pub async fn emit(&self, event: &'static str, payload: serde_json::Value) {
35 let snapshot: Vec<Arc<dyn Listener>> = self
36 .inner
37 .read()
38 .unwrap()
39 .get(event)
40 .cloned()
41 .unwrap_or_default();
42 let futs = snapshot.iter().map(|l| l.on_event(&payload));
43 join_all(futs).await;
44 }
45}