reifydb_core/event/
macro.rs1#[macro_export]
5macro_rules! define_event {
6
7 (
8 $(#[$meta:meta])*
9 $vis:vis struct $name:ident {}
10 ) => {
11 $(#[$meta])*
12 #[derive(Debug, Clone)]
13 $vis struct $name {}
14
15 impl $name {
16 #[allow(clippy::new_without_default)]
17 pub fn new() -> Self {
18 Self {}
19 }
20 }
21
22 impl $crate::event::Event for $name {
23 fn as_any(&self) -> &dyn std::any::Any {
24 self
25 }
26
27 fn into_any(self) -> Box<dyn std::any::Any + Send> {
28 Box::new(self)
29 }
30 }
31 };
32
33
34 (
35 $(#[$meta:meta])*
36 $vis:vis struct $name:ident {
37 $(
38 $(#[$field_meta:meta])*
39 $field_vis:vis $field:ident: $field_ty:ty
40 ),* $(,)?
41 }
42 ) => {
43
44 ::paste::paste! {
45
46 #[doc(hidden)]
47 #[allow(non_snake_case)]
48 mod [<__inner_ $name:snake>] {
49 #[allow(unused_imports)]
50 use super::*;
51
52 #[derive(Debug)]
53 #[allow(dead_code)]
54 pub(super) struct Inner {
55 $(
56 $(#[$field_meta])*
57 pub(super) $field: $field_ty,
58 )*
59 }
60 }
61
62
63 $(#[$meta])*
64 #[derive(Debug)]
65 $vis struct $name {
66 inner: std::sync::Arc<[<__inner_ $name:snake>]::Inner>,
67 }
68
69
70 impl Clone for $name {
71 fn clone(&self) -> Self {
72 Self {
73 inner: std::sync::Arc::clone(&self.inner),
74 }
75 }
76 }
77
78
79 impl $name {
80 #[allow(clippy::too_many_arguments)]
81 #[allow(clippy::new_without_default)]
82 pub fn new($($field: $field_ty),*) -> Self {
83 Self {
84 inner: std::sync::Arc::new([<__inner_ $name:snake>]::Inner {
85 $($field),*
86 }),
87 }
88 }
89
90 $(
91 #[allow(dead_code)]
92 pub fn $field(&self) -> &$field_ty {
93 &self.inner.$field
94 }
95 )*
96 }
97
98
99 impl $crate::event::Event for $name {
100 fn as_any(&self) -> &dyn std::any::Any {
101 self
102 }
103
104 fn into_any(self) -> Box<dyn std::any::Any + Send> {
105 Box::new(self)
106 }
107 }
108 }
109 };
110}
111
112#[cfg(test)]
113mod tests {
114 use std::{sync::Arc, thread};
115
116 use reifydb_runtime::{
117 actor::system::ActorSystem,
118 context::clock::Clock,
119 pool::{PoolConfig, Pools},
120 sync::mutex::Mutex,
121 };
122
123 use crate::event::{Event, EventBus, EventListener};
124
125 define_event! {
126 pub struct DefineTestEvent {
127 pub data: Vec<i32>,
128 pub name: String,
129 }
130 }
131
132 define_event! {
133 pub struct EmptyDefineEvent {}
134 }
135
136 #[test]
137 fn testine_event_cheap_clone() {
138 let large_vec = vec![0; 10_000];
139 let event = DefineTestEvent::new(large_vec, "test".to_string());
140
141 let clone1 = event.clone();
143 let clone2 = event.clone();
144
145 assert!(Arc::ptr_eq(&event.inner, &clone1.inner));
146 assert!(Arc::ptr_eq(&event.inner, &clone2.inner));
147
148 assert_eq!(event.data().len(), 10_000);
149 assert_eq!(clone1.data().len(), 10_000);
150 assert_eq!(clone2.data().len(), 10_000);
151 }
152
153 #[test]
154 fn testine_event_field_access() {
155 let event = DefineTestEvent::new(vec![1, 2, 3], "my_event".to_string());
156
157 assert_eq!(event.data(), &vec![1, 2, 3]);
158 assert_eq!(event.name(), "my_event");
159
160 let _data_ref: &Vec<i32> = event.data();
162 let _name_ref: &String = event.name();
163 }
164
165 #[test]
166 fn testine_event_empty_struct() {
167 let event = EmptyDefineEvent::new();
168 let clone = event.clone();
169
170 let _ = clone;
171 }
172
173 #[test]
174 fn testine_event_implements_event_trait() {
175 let event = DefineTestEvent::new(vec![42], "test".to_string());
176
177 let any_ref = event.as_any();
178 assert!(any_ref.downcast_ref::<DefineTestEvent>().is_some());
179
180 let event2 = DefineTestEvent::new(vec![99], "test2".to_string());
181 let any_box = event2.into_any();
182 assert!(any_box.downcast::<DefineTestEvent>().is_ok());
183 }
184
185 #[test]
186 fn testine_event_send_sync() {
187 fn assert_send<T: Send>() {}
188 fn assert_sync<T: Sync>() {}
189
190 assert_send::<DefineTestEvent>();
191 assert_sync::<DefineTestEvent>();
192
193 let event = DefineTestEvent::new(vec![1, 2, 3], "thread_test".to_string());
194 let handle = thread::spawn(move || {
195 assert_eq!(event.data(), &vec![1, 2, 3]);
196 });
197 handle.join().unwrap();
198 }
199
200 #[test]
201 fn testine_event_with_event_bus() {
202 let pools = Pools::new(PoolConfig::default());
203 let actor_system = ActorSystem::new(pools, Clock::Real);
204 let event_bus = EventBus::new(&actor_system.spawner());
205
206 #[derive(Clone)]
207 struct DefineTestListener {
208 counter: Arc<Mutex<i32>>,
209 }
210
211 impl EventListener<DefineTestEvent> for DefineTestListener {
212 fn on(&self, event: &DefineTestEvent) {
213 let mut c = self.counter.lock();
214 *c += event.data().len() as i32;
215 }
216 }
217
218 let listener = DefineTestListener {
219 counter: Arc::new(Mutex::new(0)),
220 };
221
222 event_bus.register::<DefineTestEvent, DefineTestListener>(listener.clone());
223
224 event_bus.emit(DefineTestEvent::new(vec![1, 2, 3], "test".to_string()));
225 event_bus.wait_for_completion();
226 assert_eq!(*listener.counter.lock(), 3);
227
228 event_bus.emit(DefineTestEvent::new(vec![1, 2, 3, 4, 5], "test2".to_string()));
229 event_bus.wait_for_completion();
230 assert_eq!(*listener.counter.lock(), 8);
231 }
232}