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