mod_events/
listener.rs

1//! Event listener traits and implementations
2
3use crate::{Event, Priority};
4
5/// Trait for synchronous event listeners
6///
7/// Implement this trait to create reusable event listeners.
8/// For simple cases, you can use closures with the dispatcher's
9/// `subscribe` or `on` methods instead.
10///
11/// # Example
12///
13/// ```rust
14/// use mod_events::{Event, EventListener, Priority};
15///
16/// #[derive(Debug, Clone)]
17/// struct UserRegistered {
18///     user_id: u64,
19///     email: String,
20/// }
21///
22/// impl Event for UserRegistered {
23///     fn as_any(&self) -> &dyn std::any::Any {
24///         self
25///     }
26/// }
27///
28/// struct EmailNotifier;
29///
30/// impl EventListener<UserRegistered> for EmailNotifier {
31///     fn handle(&self, event: &UserRegistered) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
32///         // Send email logic here
33///         println!("Sending email to {}", event.email);
34///         Ok(())
35///     }
36///     
37///     fn priority(&self) -> Priority {
38///         Priority::High
39///     }
40/// }
41/// ```
42pub trait EventListener<T: Event>: Send + Sync {
43    /// Handle the event
44    ///
45    /// This method is called when the event is dispatched.
46    /// Return `Ok(())` on success or an error on failure.
47    fn handle(&self, event: &T) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
48
49    /// Get the priority of this listener
50    ///
51    /// Higher priority listeners are executed first.
52    /// Default is `Priority::Normal`.
53    fn priority(&self) -> Priority {
54        Priority::Normal
55    }
56}
57
58/// Internal listener wrapper for type erasure
59type ListenerHandler =
60    dyn Fn(&dyn Event) -> Result<(), Box<dyn std::error::Error + Send + Sync>> + Send + Sync;
61
62pub(crate) struct ListenerWrapper {
63    pub(crate) handler: Box<ListenerHandler>,
64    pub(crate) priority: Priority,
65    pub(crate) id: usize,
66}
67
68impl std::fmt::Debug for ListenerWrapper {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        f.debug_struct("ListenerWrapper")
71            .field("priority", &self.priority)
72            .field("id", &self.id)
73            .field("handler", &"<function>")
74            .finish()
75    }
76}
77
78impl ListenerWrapper {
79    pub(crate) fn new<T, F>(listener: F, priority: Priority, id: usize) -> Self
80    where
81        T: Event + 'static,
82        F: Fn(&T) -> Result<(), Box<dyn std::error::Error + Send + Sync>> + Send + Sync + 'static,
83    {
84        Self {
85            handler: Box::new(move |event: &dyn Event| {
86                if let Some(concrete_event) = event.as_any().downcast_ref::<T>() {
87                    listener(concrete_event)
88                } else {
89                    Ok(())
90                }
91            }),
92            priority,
93            id,
94        }
95    }
96}