1use crate::{BoxFuture, Container, Injectable, Module, ModuleMetadata, Result};
2use std::{
3 any::{Any, TypeId},
4 collections::HashMap,
5 marker::PhantomData,
6 sync::{Arc, RwLock},
7};
8
9#[diagnostic::on_unimplemented(
10 message = "`{Self}` is not an event handler for `{E}`",
11 label = "missing `impl EventHandler<{E}> for {Self}`",
12 note = "add `impl EventHandler<{E}> for {Self}` or use the correct event type in `.event_handler_for::<Event, Handler>()`"
13)]
14pub trait EventHandler<E>: Send + Sync + 'static {
15 fn handle(&self, event: E) -> BoxFuture<'_, Result<()>>;
16}
17
18#[diagnostic::on_unimplemented(
19 message = "`{Self}` cannot be registered with `.event_handler::<{Self}>()` yet",
20 label = "missing `impl RegisterableEventHandler for {Self}`",
21 note = "add `impl RegisterableEventHandler for {Self} {{ type Event = YourEvent; }}` or use `.event_handler_for::<YourEvent, {Self}>()`"
22)]
23pub trait RegisterableEventHandler: Injectable {
24 type Event: Clone + Send + Sync + 'static;
25
26 fn register_into(handler: Arc<Self>, bus: &EventBus)
27 where
28 Self: Sized + EventHandler<Self::Event>,
29 {
30 bus.register::<Self::Event, Self>(handler);
31 }
32}
33
34trait ErasedHandler: Send + Sync {
35 fn handle_erased(&self, event: &dyn Any) -> BoxFuture<'_, Result<()>>;
36}
37
38struct TypedHandler<E, H> {
39 handler: Arc<H>,
40 _marker: PhantomData<E>,
41}
42
43impl<E, H> ErasedHandler for TypedHandler<E, H>
44where
45 E: Clone + Send + Sync + 'static,
46 H: EventHandler<E>,
47{
48 fn handle_erased(&self, event: &dyn Any) -> BoxFuture<'_, Result<()>> {
49 let event = event
50 .downcast_ref::<E>()
51 .expect("event type mismatch")
52 .clone();
53 let handler = self.handler.clone();
54
55 Box::pin(async move { handler.handle(event).await })
56 }
57}
58
59pub struct EventBus {
60 handlers: RwLock<HashMap<TypeId, Vec<Arc<dyn ErasedHandler>>>>,
61}
62
63impl EventBus {
64 pub fn new() -> Self {
65 Self {
66 handlers: RwLock::new(HashMap::new()),
67 }
68 }
69
70 pub fn register<E, H>(&self, handler: Arc<H>)
71 where
72 E: Clone + Send + Sync + 'static,
73 H: EventHandler<E>,
74 {
75 let wrapped = Arc::new(TypedHandler::<E, H> {
76 handler,
77 _marker: PhantomData,
78 });
79
80 self.handlers
81 .write()
82 .expect("event handler registry lock poisoned")
83 .entry(TypeId::of::<E>())
84 .or_default()
85 .push(wrapped);
86 }
87
88 pub async fn emit<E>(&self, event: E) -> Result<()>
89 where
90 E: Clone + Send + Sync + 'static,
91 {
92 let handlers = self
93 .handlers
94 .read()
95 .expect("event handler registry lock poisoned")
96 .get(&TypeId::of::<E>())
97 .cloned();
98
99 if let Some(handlers) = handlers {
100 for handler in handlers {
101 handler.handle_erased(&event).await?;
102 }
103 }
104
105 Ok(())
106 }
107
108 pub fn handler_count<E>(&self) -> usize
109 where
110 E: Clone + Send + Sync + 'static,
111 {
112 self.handlers
113 .read()
114 .expect("event handler registry lock poisoned")
115 .get(&TypeId::of::<E>())
116 .map_or(0, Vec::len)
117 }
118}
119
120impl Default for EventBus {
121 fn default() -> Self {
122 Self::new()
123 }
124}
125
126impl Injectable for EventBus {
127 fn create(_container: &Container) -> BoxFuture<'_, Self> {
128 Box::pin(async { Self::new() })
129 }
130}
131
132pub struct EventModule;
133
134impl Module for EventModule {
135 fn register() -> ModuleMetadata {
136 ModuleMetadata::new().provider::<EventBus>()
137 }
138}
139
140pub struct EventHandlerDef {
141 type_id: TypeId,
142 type_name: &'static str,
143 register_fn: Box<dyn Fn(&Container) + Send + Sync>,
144}
145
146impl EventHandlerDef {
147 pub(crate) fn of<H>() -> Self
148 where
149 H: RegisterableEventHandler + EventHandler<H::Event>,
150 {
151 Self {
152 type_id: TypeId::of::<H>(),
153 type_name: std::any::type_name::<H>(),
154 register_fn: Box::new(|container| {
155 let handler = container.resolve::<H>();
156 let bus = container.resolve::<EventBus>();
157 H::register_into(handler, &bus);
158 }),
159 }
160 }
161
162 pub(crate) fn for_event<E, H>() -> Self
163 where
164 E: Clone + Send + Sync + 'static,
165 H: Injectable + EventHandler<E>,
166 {
167 Self {
168 type_id: TypeId::of::<H>(),
169 type_name: std::any::type_name::<H>(),
170 register_fn: Box::new(|container| {
171 let handler = container.resolve::<H>();
172 let bus = container.resolve::<EventBus>();
173 bus.register::<E, H>(handler);
174 }),
175 }
176 }
177
178 pub(crate) fn try_assert_registered(&self, container: &Container) -> Result<()> {
179 if container.contains_type_id(self.type_id) {
180 return Ok(());
181 }
182
183 Err(crate::exception::startup_error(format!(
184 "missing event handler provider at startup: {} was declared by module metadata but was not registered as a provider",
185 self.type_name
186 )))
187 }
188
189 pub(crate) fn register(&self, container: &Container) {
190 (self.register_fn)(container);
191 }
192}