mod_events/core.rs
1//! Core event system traits and types
2
3use std::any::{Any, TypeId};
4use std::fmt;
5
6/// Core trait that all events must implement
7///
8/// This trait provides the foundation for type-safe event dispatch.
9/// All event types must implement this trait to be used with the dispatcher.
10///
11/// # Example
12///
13/// ```rust
14/// use mod_events::Event;
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/// ```
28pub trait Event: Any + Send + Sync + fmt::Debug {
29 /// Returns the event as [`Any`] for downcasting.
30 fn as_any(&self) -> &dyn Any;
31
32 /// Returns the unique [`TypeId`] identifier for this event type.
33 ///
34 /// Equivalent to `<Self as Any>::type_id(self)` since `Event`
35 /// requires the [`Any`] supertrait. Both methods are available and
36 /// return identical values; this one is provided for ergonomics
37 /// when working with `&dyn Event` trait objects, where the
38 /// supertrait method requires a `&dyn Any` cast first.
39 fn type_id(&self) -> TypeId {
40 TypeId::of::<Self>()
41 }
42
43 /// Returns the event name for debugging / logging.
44 ///
45 /// Backed by [`std::any::type_name`]. The exact format is
46 /// **not stable** across compiler versions — the Rust standard
47 /// library reserves the right to change `type_name` output
48 /// between releases. Treat the result as opaque human-readable
49 /// text. Do not parse it, persist it, or use it as a stable
50 /// cross-process identifier; use [`Event::type_id`] for that
51 /// instead.
52 fn event_name(&self) -> &'static str {
53 std::any::type_name::<Self>()
54 }
55}
56
57/// Unique identifier for event listeners
58///
59/// This is returned when subscribing to events and can be used
60/// to unsubscribe specific listeners later.
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
62pub struct ListenerId {
63 pub(crate) id: usize,
64 pub(crate) type_id: TypeId,
65}
66
67impl ListenerId {
68 pub(crate) fn new(id: usize, type_id: TypeId) -> Self {
69 Self { id, type_id }
70 }
71}