reifydb_core/event/
macro.rs1#[macro_export]
30macro_rules! define_event {
31 (
33 $(#[$meta:meta])*
34 $vis:vis struct $name:ident {}
35 ) => {
36 $(#[$meta])*
37 #[derive(Debug, Clone)]
38 $vis struct $name {}
39
40 impl $name {
41 #[allow(clippy::new_without_default)]
42 pub fn new() -> Self {
43 Self {}
44 }
45 }
46
47 impl $crate::event::Event for $name {
48 fn as_any(&self) -> &dyn std::any::Any {
49 self
50 }
51
52 fn into_any(self) -> Box<dyn std::any::Any + Send> {
53 Box::new(self)
54 }
55 }
56 };
57
58 (
60 $(#[$meta:meta])*
61 $vis:vis struct $name:ident {
62 $(
63 $(#[$field_meta:meta])*
64 $field_vis:vis $field:ident: $field_ty:ty
65 ),* $(,)?
66 }
67 ) => {
68 ::paste::paste! {
70 #[doc(hidden)]
72 #[allow(non_snake_case)]
73 mod [<__inner_ $name:snake>] {
74 #[allow(unused_imports)]
75 use super::*;
76
77 #[derive(Debug)]
78 #[allow(dead_code)]
79 pub(super) struct Inner {
80 $(
81 $(#[$field_meta])*
82 pub(super) $field: $field_ty,
83 )*
84 }
85 }
86
87 $(#[$meta])*
89 #[derive(Debug)]
90 $vis struct $name {
91 inner: std::sync::Arc<[<__inner_ $name:snake>]::Inner>,
92 }
93
94 impl Clone for $name {
96 fn clone(&self) -> Self {
97 Self {
98 inner: std::sync::Arc::clone(&self.inner),
99 }
100 }
101 }
102
103 impl $name {
105 #[allow(clippy::too_many_arguments)]
106 #[allow(clippy::new_without_default)]
107 pub fn new($($field: $field_ty),*) -> Self {
108 Self {
109 inner: std::sync::Arc::new([<__inner_ $name:snake>]::Inner {
110 $($field),*
111 }),
112 }
113 }
114
115 $(
116 #[allow(dead_code)]
117 pub fn $field(&self) -> &$field_ty {
118 &self.inner.$field
119 }
120 )*
121 }
122
123 impl $crate::event::Event for $name {
125 fn as_any(&self) -> &dyn std::any::Any {
126 self
127 }
128
129 fn into_any(self) -> Box<dyn std::any::Any + Send> {
130 Box::new(self)
131 }
132 }
133 }
134 };
135}
136
137#[cfg(test)]
138mod tests {
139 use std::sync::{Arc, Mutex};
140
141 use crate::event::{Event, EventBus, EventListener};
142
143 define_event! {
144 pub struct DefineTestEvent {
145 pub data: Vec<i32>,
146 pub name: String,
147 }
148 }
149
150 define_event! {
151 pub struct EmptyDefineEvent {}
152 }
153
154 #[test]
155 fn test_define_event_cheap_clone() {
156 let large_vec = vec![0; 10_000];
157 let event = DefineTestEvent::new(large_vec, "test".to_string());
158
159 let clone1 = event.clone();
161 let clone2 = event.clone();
162
163 assert!(Arc::ptr_eq(&event.inner, &clone1.inner));
165 assert!(Arc::ptr_eq(&event.inner, &clone2.inner));
166
167 assert_eq!(event.data().len(), 10_000);
169 assert_eq!(clone1.data().len(), 10_000);
170 assert_eq!(clone2.data().len(), 10_000);
171 }
172
173 #[test]
174 fn test_define_event_field_access() {
175 let event = DefineTestEvent::new(vec![1, 2, 3], "my_event".to_string());
176
177 assert_eq!(event.data(), &vec![1, 2, 3]);
178 assert_eq!(event.name(), "my_event");
179
180 let _data_ref: &Vec<i32> = event.data();
182 let _name_ref: &String = event.name();
183 }
184
185 #[test]
186 fn test_define_event_empty_struct() {
187 let event = EmptyDefineEvent::new();
188 let clone = event.clone();
189
190 drop(event);
192 drop(clone);
193 }
194
195 #[test]
196 fn test_define_event_implements_event_trait() {
197 let event = DefineTestEvent::new(vec![42], "test".to_string());
198
199 let any_ref = event.as_any();
201 assert!(any_ref.downcast_ref::<DefineTestEvent>().is_some());
202
203 let event2 = DefineTestEvent::new(vec![99], "test2".to_string());
204 let any_box = event2.into_any();
205 assert!(any_box.downcast::<DefineTestEvent>().is_ok());
206 }
207
208 #[test]
209 fn test_define_event_send_sync() {
210 fn assert_send<T: Send>() {}
212 fn assert_sync<T: Sync>() {}
213
214 assert_send::<DefineTestEvent>();
215 assert_sync::<DefineTestEvent>();
216
217 let event = DefineTestEvent::new(vec![1, 2, 3], "thread_test".to_string());
219 let handle = std::thread::spawn(move || {
220 assert_eq!(event.data(), &vec![1, 2, 3]);
221 });
222 handle.join().unwrap();
223 }
224
225 #[test]
226 fn test_define_event_with_event_bus() {
227 let actor_system = reifydb_runtime::actor::system::ActorSystem::new(
228 reifydb_runtime::SharedRuntimeConfig::default().actor_system_config(),
229 );
230 let event_bus = EventBus::new(&actor_system);
231
232 #[derive(Clone)]
234 struct DefineTestListener {
235 counter: Arc<Mutex<i32>>,
236 }
237
238 impl EventListener<DefineTestEvent> for DefineTestListener {
239 fn on(&self, event: &DefineTestEvent) {
240 let mut c = self.counter.lock().unwrap();
241 *c += event.data().len() as i32;
242 }
243 }
244
245 let listener = DefineTestListener {
246 counter: Arc::new(Mutex::new(0)),
247 };
248
249 event_bus.register::<DefineTestEvent, DefineTestListener>(listener.clone());
250
251 event_bus.emit(DefineTestEvent::new(vec![1, 2, 3], "test".to_string()));
253 event_bus.wait_for_completion();
254 assert_eq!(*listener.counter.lock().unwrap(), 3);
255
256 event_bus.emit(DefineTestEvent::new(vec![1, 2, 3, 4, 5], "test2".to_string()));
258 event_bus.wait_for_completion();
259 assert_eq!(*listener.counter.lock().unwrap(), 8);
260 }
261}