1#![allow(dead_code)]
4
5pub struct DomainEvent {
6 pub id: u64,
7 pub aggregate_id: u64,
8 pub event_type: String,
9 pub payload: String,
10 pub timestamp_ms: u64,
11}
12
13pub fn new_domain_event(
14 id: u64,
15 agg_id: u64,
16 event_type: &str,
17 payload: &str,
18 ts: u64,
19) -> DomainEvent {
20 DomainEvent {
21 id,
22 aggregate_id: agg_id,
23 event_type: event_type.to_string(),
24 payload: payload.to_string(),
25 timestamp_ms: ts,
26 }
27}
28
29pub fn event_to_json(e: &DomainEvent) -> String {
30 format!(
31 "{{\"id\":{},\"aggregate_id\":{},\"event_type\":\"{}\",\"payload\":\"{}\",\"timestamp_ms\":{}}}",
32 e.id, e.aggregate_id, e.event_type, e.payload, e.timestamp_ms
33 )
34}
35
36pub fn event_is_type(e: &DomainEvent, t: &str) -> bool {
37 e.event_type == t
38}
39
40pub fn events_by_aggregate(events: &[DomainEvent], agg_id: u64) -> Vec<&DomainEvent> {
41 events.iter().filter(|e| e.aggregate_id == agg_id).collect()
42}
43
44pub fn events_after(events: &[DomainEvent], ts: u64) -> Vec<&DomainEvent> {
45 events.iter().filter(|e| e.timestamp_ms > ts).collect()
46}
47
48pub fn events_of_type<'a>(events: &'a [DomainEvent], t: &str) -> Vec<&'a DomainEvent> {
49 events.iter().filter(|e| e.event_type == t).collect()
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn test_new_domain_event() {
58 let e = new_domain_event(1, 10, "Created", "{}", 1000);
60 assert_eq!(e.id, 1);
61 assert_eq!(e.aggregate_id, 10);
62 assert!(event_is_type(&e, "Created"));
63 }
64
65 #[test]
66 fn test_event_to_json() {
67 let e = new_domain_event(1, 2, "Test", "data", 500);
69 let j = event_to_json(&e);
70 assert!(j.contains("\"id\":1"));
71 assert!(j.contains("\"event_type\":\"Test\""));
72 }
73
74 #[test]
75 fn test_events_by_aggregate() {
76 let events = vec![
78 new_domain_event(1, 10, "A", "", 100),
79 new_domain_event(2, 20, "B", "", 200),
80 new_domain_event(3, 10, "C", "", 300),
81 ];
82 let r = events_by_aggregate(&events, 10);
83 assert_eq!(r.len(), 2);
84 }
85
86 #[test]
87 fn test_events_after() {
88 let events = vec![
90 new_domain_event(1, 1, "A", "", 100),
91 new_domain_event(2, 1, "B", "", 200),
92 new_domain_event(3, 1, "C", "", 300),
93 ];
94 let r = events_after(&events, 150);
95 assert_eq!(r.len(), 2);
96 }
97
98 #[test]
99 fn test_events_of_type() {
100 let events = vec![
102 new_domain_event(1, 1, "Created", "", 100),
103 new_domain_event(2, 1, "Updated", "", 200),
104 new_domain_event(3, 1, "Created", "", 300),
105 ];
106 let r = events_of_type(&events, "Created");
107 assert_eq!(r.len(), 2);
108 }
109
110 #[test]
111 fn test_event_is_type_false() {
112 let e = new_domain_event(1, 1, "A", "", 0);
114 assert!(!event_is_type(&e, "B"));
115 }
116
117 #[test]
118 fn test_events_empty() {
119 let events: Vec<DomainEvent> = vec![];
121 assert!(events_by_aggregate(&events, 1).is_empty());
122 }
123}