use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use futures::future::{join_all, BoxFuture};
pub trait Listener: Send + Sync + 'static {
fn on_event(&self, payload: &serde_json::Value) -> BoxFuture<'static, ()>;
}
type Listeners = HashMap<&'static str, Vec<Arc<dyn Listener>>>;
#[derive(Default, Clone)]
pub struct EventBus {
inner: Arc<RwLock<Listeners>>,
}
impl EventBus {
pub fn new() -> Self {
Self::default()
}
pub fn subscribe(&self, event: &'static str, listener: Arc<dyn Listener>) {
self.inner
.write()
.unwrap()
.entry(event)
.or_default()
.push(listener);
}
pub async fn emit(&self, event: &'static str, payload: serde_json::Value) {
let snapshot: Vec<Arc<dyn Listener>> = self
.inner
.read()
.unwrap()
.get(event)
.cloned()
.unwrap_or_default();
let futs = snapshot.iter().map(|l| l.on_event(&payload));
join_all(futs).await;
}
}