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