Skip to main content

backbone_messaging/
event.rs

1//! Domain Event trait definition
2
3use chrono::{DateTime, Utc};
4
5/// Trait for domain events
6///
7/// All domain events must implement this trait to be used with the EventBus.
8/// Domain events represent something that happened in the domain that domain
9/// experts care about.
10///
11/// # Example
12///
13/// ```rust,ignore
14/// use backbone_messaging::DomainEvent;
15/// use chrono::{DateTime, Utc};
16///
17/// #[derive(Clone, Debug)]
18/// struct OrderPlaced {
19///     order_id: String,
20///     customer_id: String,
21///     total: f64,
22///     placed_at: DateTime<Utc>,
23/// }
24///
25/// impl DomainEvent for OrderPlaced {
26///     fn event_type(&self) -> &'static str {
27///         "OrderPlaced"
28///     }
29///
30///     fn aggregate_id(&self) -> &str {
31///         &self.order_id
32///     }
33///
34///     fn occurred_at(&self) -> DateTime<Utc> {
35///         self.placed_at
36///     }
37/// }
38/// ```
39pub trait DomainEvent: Clone + Send + Sync + 'static {
40    /// Returns the event type name (e.g., "UserCreated", "OrderPlaced")
41    fn event_type(&self) -> &'static str;
42
43    /// Returns the aggregate ID this event belongs to
44    fn aggregate_id(&self) -> &str;
45
46    /// Returns when the event occurred
47    /// Default implementation returns current time
48    fn occurred_at(&self) -> DateTime<Utc> {
49        Utc::now()
50    }
51
52    /// Returns the aggregate type name (e.g., "User", "Order")
53    /// Default implementation extracts from event type
54    fn aggregate_type(&self) -> &'static str {
55        // Extract aggregate type from event type (e.g., "UserCreated" -> "User")
56        let event_type = self.event_type();
57        // Simple heuristic: find common suffixes
58        for suffix in ["Created", "Updated", "Deleted", "Changed", "Added", "Removed"] {
59            if event_type.ends_with(suffix) {
60                // Return the part before the suffix
61                // This is a compile-time approximation
62                return event_type;
63            }
64        }
65        event_type
66    }
67
68    /// Returns the event version for schema evolution
69    fn version(&self) -> u32 {
70        1
71    }
72}
73
74/// Marker trait for events that can be serialized
75#[allow(dead_code)]
76pub trait SerializableEvent: DomainEvent + serde::Serialize + serde::de::DeserializeOwned {}
77
78impl<T> SerializableEvent for T where T: DomainEvent + serde::Serialize + serde::de::DeserializeOwned {}