Skip to main content

reifydb_transaction/interceptor/
filtered.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4//! Filtered interceptor wrappers that only execute when the filter matches.
5//!
6//! These wrappers check the entity name against the filter before invoking the handler.
7//! Note: Namespace filtering requires namespace name resolution which is currently a TODO.
8
9use reifydb_type::Result;
10
11use super::{
12	filter::InterceptFilter,
13	namespace::{
14		NamespacePostCreateContext, NamespacePostCreateInterceptor, NamespacePostUpdateContext,
15		NamespacePostUpdateInterceptor, NamespacePreDeleteContext, NamespacePreDeleteInterceptor,
16		NamespacePreUpdateContext, NamespacePreUpdateInterceptor,
17	},
18	ringbuffer::{
19		RingBufferPostDeleteContext, RingBufferPostDeleteInterceptor, RingBufferPostInsertContext,
20		RingBufferPostInsertInterceptor, RingBufferPostUpdateContext, RingBufferPostUpdateInterceptor,
21		RingBufferPreDeleteContext, RingBufferPreDeleteInterceptor, RingBufferPreInsertContext,
22		RingBufferPreInsertInterceptor, RingBufferPreUpdateContext, RingBufferPreUpdateInterceptor,
23	},
24	ringbuffer_def::{
25		RingBufferDefPostCreateContext, RingBufferDefPostCreateInterceptor, RingBufferDefPostUpdateContext,
26		RingBufferDefPostUpdateInterceptor, RingBufferDefPreDeleteContext, RingBufferDefPreDeleteInterceptor,
27		RingBufferDefPreUpdateContext, RingBufferDefPreUpdateInterceptor,
28	},
29	table::{
30		TablePostDeleteContext, TablePostDeleteInterceptor, TablePostInsertContext, TablePostInsertInterceptor,
31		TablePostUpdateContext, TablePostUpdateInterceptor, TablePreDeleteContext, TablePreDeleteInterceptor,
32		TablePreInsertContext, TablePreInsertInterceptor, TablePreUpdateContext, TablePreUpdateInterceptor,
33	},
34	table_def::{
35		TableDefPostCreateContext, TableDefPostCreateInterceptor, TableDefPostUpdateContext,
36		TableDefPostUpdateInterceptor, TableDefPreDeleteContext, TableDefPreDeleteInterceptor,
37		TableDefPreUpdateContext, TableDefPreUpdateInterceptor,
38	},
39	view::{
40		ViewPostDeleteContext, ViewPostDeleteInterceptor, ViewPostInsertContext, ViewPostInsertInterceptor,
41		ViewPostUpdateContext, ViewPostUpdateInterceptor, ViewPreDeleteContext, ViewPreDeleteInterceptor,
42		ViewPreInsertContext, ViewPreInsertInterceptor, ViewPreUpdateContext, ViewPreUpdateInterceptor,
43	},
44	view_def::{
45		ViewDefPostCreateContext, ViewDefPostCreateInterceptor, ViewDefPostUpdateContext,
46		ViewDefPostUpdateInterceptor, ViewDefPreDeleteContext, ViewDefPreDeleteInterceptor,
47		ViewDefPreUpdateContext, ViewDefPreUpdateInterceptor,
48	},
49};
50
51/// Macro to generate filtered interceptor wrapper types.
52///
53/// The 4-arg form accesses the entity name via `ctx.$entity_field.name` (for struct types).
54/// The 5-arg form accesses it via `ctx.$entity_field.$name_method()` (for enum types like Namespace).
55macro_rules! define_filtered_interceptor {
56	(
57		$wrapper_name:ident,
58		$trait_name:ident,
59		$context_type:ident,
60		$entity_field:ident
61	) => {
62		/// Filtered interceptor wrapper that checks entity name before executing.
63		pub struct $wrapper_name<F>
64		where
65			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync,
66		{
67			filter: InterceptFilter,
68			handler: F,
69		}
70
71		impl<F> $wrapper_name<F>
72		where
73			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync,
74		{
75			pub fn new(filter: InterceptFilter, handler: F) -> Self {
76				Self {
77					filter,
78					handler,
79				}
80			}
81		}
82
83		impl<F> Clone for $wrapper_name<F>
84		where
85			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync + Clone,
86		{
87			fn clone(&self) -> Self {
88				Self {
89					filter: self.filter.clone(),
90					handler: self.handler.clone(),
91				}
92			}
93		}
94
95		impl<F> $trait_name for $wrapper_name<F>
96		where
97			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync,
98		{
99			fn intercept<'a>(&self, ctx: &mut $context_type<'a>) -> Result<()> {
100				let entity_name = ctx.$entity_field.name.as_str();
101				let name_matches =
102					self.filter.name.as_ref().map_or(true, |n| n.as_str() == entity_name);
103				if name_matches {
104					(self.handler)(ctx)
105				} else {
106					Ok(())
107				}
108			}
109		}
110	};
111	(
112		$wrapper_name:ident,
113		$trait_name:ident,
114		$context_type:ident,
115		$entity_field:ident,
116		$name_method:ident
117	) => {
118		/// Filtered interceptor wrapper that checks entity name before executing.
119		pub struct $wrapper_name<F>
120		where
121			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync,
122		{
123			filter: InterceptFilter,
124			handler: F,
125		}
126
127		impl<F> $wrapper_name<F>
128		where
129			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync,
130		{
131			pub fn new(filter: InterceptFilter, handler: F) -> Self {
132				Self {
133					filter,
134					handler,
135				}
136			}
137		}
138
139		impl<F> Clone for $wrapper_name<F>
140		where
141			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync + Clone,
142		{
143			fn clone(&self) -> Self {
144				Self {
145					filter: self.filter.clone(),
146					handler: self.handler.clone(),
147				}
148			}
149		}
150
151		impl<F> $trait_name for $wrapper_name<F>
152		where
153			F: for<'a> Fn(&mut $context_type<'a>) -> Result<()> + Send + Sync,
154		{
155			fn intercept<'a>(&self, ctx: &mut $context_type<'a>) -> Result<()> {
156				let entity_name = ctx.$entity_field.$name_method();
157				let name_matches =
158					self.filter.name.as_ref().map_or(true, |n| n.as_str() == entity_name);
159				if name_matches {
160					(self.handler)(ctx)
161				} else {
162					Ok(())
163				}
164			}
165		}
166	};
167}
168
169// Table filtered interceptors
170define_filtered_interceptor!(
171	FilteredTablePreInsertInterceptor,
172	TablePreInsertInterceptor,
173	TablePreInsertContext,
174	table
175);
176
177define_filtered_interceptor!(
178	FilteredTablePostInsertInterceptor,
179	TablePostInsertInterceptor,
180	TablePostInsertContext,
181	table
182);
183
184define_filtered_interceptor!(
185	FilteredTablePreUpdateInterceptor,
186	TablePreUpdateInterceptor,
187	TablePreUpdateContext,
188	table
189);
190
191define_filtered_interceptor!(
192	FilteredTablePostUpdateInterceptor,
193	TablePostUpdateInterceptor,
194	TablePostUpdateContext,
195	table
196);
197
198define_filtered_interceptor!(
199	FilteredTablePreDeleteInterceptor,
200	TablePreDeleteInterceptor,
201	TablePreDeleteContext,
202	table
203);
204
205define_filtered_interceptor!(
206	FilteredTablePostDeleteInterceptor,
207	TablePostDeleteInterceptor,
208	TablePostDeleteContext,
209	table
210);
211
212// Ring buffer filtered interceptors
213define_filtered_interceptor!(
214	FilteredRingBufferPreInsertInterceptor,
215	RingBufferPreInsertInterceptor,
216	RingBufferPreInsertContext,
217	ringbuffer
218);
219
220define_filtered_interceptor!(
221	FilteredRingBufferPostInsertInterceptor,
222	RingBufferPostInsertInterceptor,
223	RingBufferPostInsertContext,
224	ringbuffer
225);
226
227define_filtered_interceptor!(
228	FilteredRingBufferPreUpdateInterceptor,
229	RingBufferPreUpdateInterceptor,
230	RingBufferPreUpdateContext,
231	ringbuffer
232);
233
234define_filtered_interceptor!(
235	FilteredRingBufferPostUpdateInterceptor,
236	RingBufferPostUpdateInterceptor,
237	RingBufferPostUpdateContext,
238	ringbuffer
239);
240
241define_filtered_interceptor!(
242	FilteredRingBufferPreDeleteInterceptor,
243	RingBufferPreDeleteInterceptor,
244	RingBufferPreDeleteContext,
245	ringbuffer
246);
247
248define_filtered_interceptor!(
249	FilteredRingBufferPostDeleteInterceptor,
250	RingBufferPostDeleteInterceptor,
251	RingBufferPostDeleteContext,
252	ringbuffer
253);
254
255// View data filtered interceptors
256define_filtered_interceptor!(FilteredViewPreInsertInterceptor, ViewPreInsertInterceptor, ViewPreInsertContext, view);
257
258define_filtered_interceptor!(FilteredViewPostInsertInterceptor, ViewPostInsertInterceptor, ViewPostInsertContext, view);
259
260define_filtered_interceptor!(FilteredViewPreUpdateInterceptor, ViewPreUpdateInterceptor, ViewPreUpdateContext, view);
261
262define_filtered_interceptor!(FilteredViewPostUpdateInterceptor, ViewPostUpdateInterceptor, ViewPostUpdateContext, view);
263
264define_filtered_interceptor!(FilteredViewPreDeleteInterceptor, ViewPreDeleteInterceptor, ViewPreDeleteContext, view);
265
266define_filtered_interceptor!(FilteredViewPostDeleteInterceptor, ViewPostDeleteInterceptor, ViewPostDeleteContext, view);
267
268// View definition filtered interceptors
269define_filtered_interceptor!(
270	FilteredViewDefPostCreateInterceptor,
271	ViewDefPostCreateInterceptor,
272	ViewDefPostCreateContext,
273	post
274);
275
276define_filtered_interceptor!(
277	FilteredViewDefPreUpdateInterceptor,
278	ViewDefPreUpdateInterceptor,
279	ViewDefPreUpdateContext,
280	pre
281);
282
283define_filtered_interceptor!(
284	FilteredViewDefPostUpdateInterceptor,
285	ViewDefPostUpdateInterceptor,
286	ViewDefPostUpdateContext,
287	pre
288);
289
290define_filtered_interceptor!(
291	FilteredViewDefPreDeleteInterceptor,
292	ViewDefPreDeleteInterceptor,
293	ViewDefPreDeleteContext,
294	pre
295);
296
297// Table definition filtered interceptors
298define_filtered_interceptor!(
299	FilteredTableDefPostCreateInterceptor,
300	TableDefPostCreateInterceptor,
301	TableDefPostCreateContext,
302	post
303);
304
305define_filtered_interceptor!(
306	FilteredTableDefPreUpdateInterceptor,
307	TableDefPreUpdateInterceptor,
308	TableDefPreUpdateContext,
309	pre
310);
311
312define_filtered_interceptor!(
313	FilteredTableDefPostUpdateInterceptor,
314	TableDefPostUpdateInterceptor,
315	TableDefPostUpdateContext,
316	pre
317);
318
319define_filtered_interceptor!(
320	FilteredTableDefPreDeleteInterceptor,
321	TableDefPreDeleteInterceptor,
322	TableDefPreDeleteContext,
323	pre
324);
325
326// Ring buffer definition filtered interceptors
327define_filtered_interceptor!(
328	FilteredRingBufferDefPostCreateInterceptor,
329	RingBufferDefPostCreateInterceptor,
330	RingBufferDefPostCreateContext,
331	post
332);
333
334define_filtered_interceptor!(
335	FilteredRingBufferDefPreUpdateInterceptor,
336	RingBufferDefPreUpdateInterceptor,
337	RingBufferDefPreUpdateContext,
338	pre
339);
340
341define_filtered_interceptor!(
342	FilteredRingBufferDefPostUpdateInterceptor,
343	RingBufferDefPostUpdateInterceptor,
344	RingBufferDefPostUpdateContext,
345	pre
346);
347
348define_filtered_interceptor!(
349	FilteredRingBufferDefPreDeleteInterceptor,
350	RingBufferDefPreDeleteInterceptor,
351	RingBufferDefPreDeleteContext,
352	pre
353);
354
355// Namespace filtered interceptors
356define_filtered_interceptor!(
357	FilteredNamespacePostCreateInterceptor,
358	NamespacePostCreateInterceptor,
359	NamespacePostCreateContext,
360	post,
361	name
362);
363
364define_filtered_interceptor!(
365	FilteredNamespacePreUpdateInterceptor,
366	NamespacePreUpdateInterceptor,
367	NamespacePreUpdateContext,
368	pre,
369	name
370);
371
372define_filtered_interceptor!(
373	FilteredNamespacePostUpdateInterceptor,
374	NamespacePostUpdateInterceptor,
375	NamespacePostUpdateContext,
376	pre,
377	name
378);
379
380define_filtered_interceptor!(
381	FilteredNamespacePreDeleteInterceptor,
382	NamespacePreDeleteInterceptor,
383	NamespacePreDeleteContext,
384	pre,
385	name
386);