reifydb_core/interceptor/
mod.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4mod builder;
5mod chain;
6mod factory;
7mod filter;
8mod filtered;
9mod interceptor;
10mod interceptors;
11mod namespace_def;
12mod ring_buffer;
13mod ring_buffer_def;
14mod table;
15mod table_def;
16mod transaction;
17mod view;
18mod view_def;
19
20pub use builder::*;
21pub use chain::InterceptorChain;
22pub use factory::{InterceptorFactory, StandardInterceptorFactory};
23pub use filter::InterceptFilter;
24pub use filtered::*;
25pub use interceptors::Interceptors;
26pub use namespace_def::*;
27pub use ring_buffer::*;
28pub use ring_buffer_def::*;
29pub use table::*;
30pub use table_def::*;
31pub use transaction::*;
32pub use view::*;
33pub use view_def::*;
34
35pub type Chain<T, I> = InterceptorChain<T, I>;
36
37/// Generic macro to define interceptor contexts, traits, and chain execution
38#[macro_export]
39macro_rules! define_interceptor {
40	// Version with Transaction type parameter
41	(
42		context: $context_name:ident<T>,
43		trait: $trait_name:ident,
44		fields: {
45			$($field_name:ident: $field_type:ty),* $(,)?
46		}
47	) => {
48		/// Context for interceptors
49		pub struct $context_name<'a, T: $crate::interface::CommandTransaction> {
50			$(pub $field_name: $field_type,)*
51		}
52
53		impl<'a, T: $crate::interface::CommandTransaction> $context_name<'a, T> {
54			pub fn new(
55				$($field_name: $field_type,)*
56			) -> Self {
57				Self {
58					$($field_name,)*
59				}
60			}
61		}
62
63		pub trait $trait_name<T: $crate::interface::CommandTransaction> {
64			fn intercept(
65				&self,
66				ctx: &mut $context_name<T>,
67			) -> $crate::Result<()>;
68		}
69
70		impl<T: $crate::interface::CommandTransaction> $crate::interceptor::InterceptorChain<T, dyn $trait_name<T>> {
71			pub fn execute(
72				&self,
73				mut ctx: $context_name<T>,
74			) -> $crate::Result<()> {
75				for interceptor in &self.interceptors {
76					interceptor.intercept(&mut ctx)?;
77				}
78				Ok(())
79			}
80		}
81	};
82
83	// Version without Transaction type parameter
84	(
85		context: $context_name:ident,
86		trait: $trait_name:ident<T>,
87		fields: {
88			$($field_name:ident: $field_type:ty),* $(,)?
89		}
90	) => {
91		/// Context for interceptors
92		pub struct $context_name {
93			$(pub $field_name: $field_type,)*
94		}
95
96		impl $context_name {
97			pub fn new(
98				$($field_name: $field_type,)*
99			) -> Self {
100				Self {
101					$($field_name,)*
102				}
103			}
104		}
105
106		pub trait $trait_name<T: $crate::interface::CommandTransaction> {
107			fn intercept(
108				&self,
109				ctx: &mut $context_name,
110			) -> $crate::Result<()>;
111		}
112
113		impl<T: $crate::interface::CommandTransaction> $crate::interceptor::InterceptorChain<T, dyn $trait_name<T>> {
114			pub fn execute(
115				&self,
116				mut ctx: $context_name,
117			) -> $crate::Result<()> {
118				for interceptor in &self.interceptors {
119					interceptor.intercept(&mut ctx)?;
120				}
121				Ok(())
122			}
123		}
124	};
125}
126
127/// Macro to generate closure interceptor wrapper types
128#[macro_export]
129macro_rules! define_closure_interceptor {
130	// Version with Transaction type parameter
131	(
132		$wrapper_name:ident,
133		$trait_name:ident,
134		$context_type:ident,
135		with_transaction
136	) => {
137		pub struct $wrapper_name<T: crate::interface::CommandTransaction, F>
138		where
139			F: Fn(&mut $context_type<T>) -> crate::Result<()>,
140		{
141			closure: F,
142			_phantom: PhantomData<T>,
143		}
144
145		impl<T: crate::interface::CommandTransaction, F> $wrapper_name<T, F>
146		where
147			F: Fn(&mut $context_type<T>) -> crate::Result<()>,
148		{
149			pub fn new(closure: F) -> Self {
150				Self {
151					closure,
152					_phantom: PhantomData,
153				}
154			}
155		}
156
157		impl<T: crate::interface::CommandTransaction, F> Clone for $wrapper_name<T, F>
158		where
159			F: Fn(&mut $context_type<T>) -> crate::Result<()> + Clone,
160		{
161			fn clone(&self) -> Self {
162				Self {
163					closure: self.closure.clone(),
164					_phantom: PhantomData,
165				}
166			}
167		}
168
169		impl<T: crate::interface::CommandTransaction, F> $trait_name<T> for $wrapper_name<T, F>
170		where
171			F: Fn(&mut $context_type<T>) -> crate::Result<()>,
172		{
173			fn intercept(&self, ctx: &mut $context_type<T>) -> crate::Result<()> {
174				(self.closure)(ctx)
175			}
176		}
177	};
178
179	// Version without Transaction type parameter in struct (but still
180	// implements trait with T)
181	(
182		$wrapper_name:ident,
183		$trait_name:ident,
184		$context_type:ident,
185		no_transaction_param
186	) => {
187		pub struct $wrapper_name<F>
188		where
189			F: Fn(&mut $context_type) -> crate::Result<()>,
190		{
191			closure: F,
192		}
193
194		impl<F> $wrapper_name<F>
195		where
196			F: Fn(&mut $context_type) -> crate::Result<()>,
197		{
198			pub fn new(closure: F) -> Self {
199				Self {
200					closure,
201				}
202			}
203		}
204
205		impl<F> Clone for $wrapper_name<F>
206		where
207			F: Fn(&mut $context_type) -> crate::Result<()> + Clone,
208		{
209			fn clone(&self) -> Self {
210				Self {
211					closure: self.closure.clone(),
212				}
213			}
214		}
215
216		impl<T: crate::interface::CommandTransaction, F> $trait_name<T> for $wrapper_name<F>
217		where
218			F: Fn(&mut $context_type) -> crate::Result<()>,
219		{
220			fn intercept(&self, ctx: &mut $context_type) -> crate::Result<()> {
221				(self.closure)(ctx)
222			}
223		}
224	};
225}
226
227/// Macro to create helper functions that create closure interceptors
228#[macro_export]
229macro_rules! define_api_function {
230	// Version with Transaction type parameter
231	(
232		$fn_name:ident,
233		$closure_type:ident<T, F>,
234		$context_type:ident<T>
235	) => {
236		pub fn $fn_name<T: crate::interface::CommandTransaction, F>(f: F) -> $closure_type<T, F>
237		where
238			F: Fn(&mut $context_type<T>) -> crate::Result<()> + Send + Sync + Clone + 'static,
239		{
240			$closure_type::new(f)
241		}
242	};
243
244	// Version without Transaction type parameter
245	(
246		$fn_name:ident,
247		$closure_type:ident<F>,
248		$context_type:ident
249	) => {
250		pub fn $fn_name<F>(f: F) -> $closure_type<F>
251		where
252			F: Fn(&mut $context_type) -> crate::Result<()> + Send + Sync + Clone + 'static,
253		{
254			$closure_type::new(f)
255		}
256	};
257}
258
259/// Trait for self-registering interceptors
260/// This allows interceptors that implement multiple interceptor traits
261/// to register themselves in all appropriate chains with a single Rc instance
262pub trait RegisterInterceptor<T: crate::interface::CommandTransaction> {
263	fn register(self: std::rc::Rc<Self>, interceptors: &mut Interceptors<T>);
264}
265
266#[macro_export]
267macro_rules! impl_register_interceptor {
268	(
269		$closure_type:ident<T, F>,
270		$context_type:ident<T>,
271		$trait_type:ident,
272		$field:ident
273	) => {
274		impl<T, F> $crate::interceptor::RegisterInterceptor<T> for $closure_type<T, F>
275		where
276			T: $crate::interface::CommandTransaction + 'static,
277			F: Fn(&mut $context_type<T>) -> $crate::Result<()> + 'static,
278		{
279			fn register(self: std::rc::Rc<Self>, interceptors: &mut $crate::interceptor::Interceptors<T>) {
280				interceptors.$field.add(self as std::rc::Rc<dyn $trait_type<T>>);
281			}
282		}
283	};
284	(
285		$closure_type:ident<F>,
286		$context_type:ident,
287		$trait_type:ident<T>,
288		$field:ident
289	) => {
290		impl<T, F> $crate::interceptor::RegisterInterceptor<T> for $closure_type<F>
291		where
292			T: $crate::interface::CommandTransaction,
293			F: Fn(&mut $context_type) -> $crate::Result<()> + 'static,
294		{
295			fn register(self: std::rc::Rc<Self>, interceptors: &mut $crate::interceptor::Interceptors<T>) {
296				interceptors.$field.add(self as std::rc::Rc<dyn $trait_type<T>>);
297			}
298		}
299	};
300}