1use std::fmt::Display;
22use std::str::FromStr;
23
24use crate::filtering::{FilterError, Operable, Operator, OperatorClass};
25
26pub trait Scalar {}
28
29impl Scalar for i8 {}
30impl Scalar for u8 {}
31impl Scalar for i16 {}
32impl Scalar for u16 {}
33impl Scalar for i32 {}
34impl Scalar for u32 {}
35impl Scalar for i64 {}
36impl Scalar for u64 {}
37impl Scalar for bool {}
38impl Scalar for String {}
39
40impl<T: chrono::TimeZone> Scalar for chrono::DateTime<T> {}
41
42impl<T> Operable for T
43where
44 T: Scalar,
45{
46 type Base = Self;
47 fn apply<O: Operator<Self::Base>>(&self, op: &O) -> bool {
48 op.apply(self)
49 }
50}
51
52pub struct ExactImpl<T> {
54 target: T,
55}
56
57impl<T> Operator<T> for ExactImpl<T>
58where
59 T: core::cmp::Eq,
60{
61 fn apply(&self, value: &T) -> bool {
62 value == &self.target
63 }
64}
65
66pub struct Exact;
68
69impl<T> OperatorClass<T> for Exact
70where
71 T: core::cmp::Eq + FromStr,
72 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
73{
74 type Instance = ExactImpl<T>;
75 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
76 Ok(ExactImpl {
77 target: T::from_str(rhs).map_err(|e| FilterError::Instantiation(e.into()))?,
78 })
79 }
80}
81
82pub struct InImpl<T> {
84 targets: Vec<T>,
85}
86
87impl<T> Operator<T> for InImpl<T>
88where
89 T: core::cmp::Eq + FromStr,
90{
91 fn apply(&self, value: &T) -> bool {
92 self.targets.contains(value)
93 }
94}
95
96pub struct In;
98
99impl<T> OperatorClass<T> for In
100where
101 T: core::cmp::Eq + FromStr,
102 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
103{
104 type Instance = InImpl<T>;
105 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
106 let mut targets = Vec::new();
107 for elt in rhs.split(',') {
108 targets.push(T::from_str(elt).map_err(|e| FilterError::Instantiation(e.into()))?);
109 }
110 Ok(InImpl { targets })
111 }
112}
113
114pub struct ContainsImpl {
116 target: String,
117}
118
119impl<T> Operator<T> for ContainsImpl
120where
121 T: Display,
122{
123 fn apply(&self, value: &T) -> bool {
124 value.to_string().contains(&self.target)
125 }
126}
127
128pub struct Contains;
130
131impl<T> OperatorClass<T> for Contains
132where
133 T: Display + FromStr,
134 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
135{
136 type Instance = ContainsImpl;
137 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
138 Ok(ContainsImpl {
139 target: rhs.to_string(),
140 })
141 }
142}
143
144pub struct IContainsImpl {
146 target: String,
147}
148
149impl<T> Operator<T> for IContainsImpl
150where
151 T: Display,
152{
153 fn apply(&self, value: &T) -> bool {
154 value.to_string().to_lowercase().contains(&self.target)
155 }
156}
157
158pub struct IContains;
160
161impl<T> OperatorClass<T> for IContains
162where
163 T: Display + FromStr,
164 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
165{
166 type Instance = IContainsImpl;
167 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
168 Ok(IContainsImpl {
169 target: rhs.to_lowercase(),
170 })
171 }
172}
173
174pub struct IExactImpl {
176 target: String,
177}
178
179impl<T> Operator<T> for IExactImpl
180where
181 T: Display,
182{
183 fn apply(&self, value: &T) -> bool {
184 value.to_string().to_lowercase() == self.target
185 }
186}
187
188pub struct IExact;
190
191impl<T> OperatorClass<T> for IExact
192where
193 T: Display + FromStr,
194 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
195{
196 type Instance = IExactImpl;
197 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
198 Ok(IExactImpl {
199 target: rhs.to_lowercase(),
200 })
201 }
202}
203
204pub struct StartsWithImpl {
206 target: String,
207}
208
209impl<T> Operator<T> for StartsWithImpl
210where
211 T: Display,
212{
213 fn apply(&self, value: &T) -> bool {
214 value.to_string().starts_with(&self.target)
215 }
216}
217
218pub struct StartsWith;
220
221impl<T> OperatorClass<T> for StartsWith
222where
223 T: Display + FromStr,
224 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
225{
226 type Instance = StartsWithImpl;
227 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
228 Ok(StartsWithImpl {
229 target: rhs.to_string(),
230 })
231 }
232}
233
234pub struct EndsWithImpl {
236 target: String,
237}
238
239impl<T> Operator<T> for EndsWithImpl
240where
241 T: Display,
242{
243 fn apply(&self, value: &T) -> bool {
244 value.to_string().ends_with(&self.target)
245 }
246}
247
248pub struct EndsWith;
250
251impl<T> OperatorClass<T> for EndsWith
252where
253 T: Display + FromStr,
254 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
255{
256 type Instance = EndsWithImpl;
257 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
258 Ok(EndsWithImpl {
259 target: rhs.to_string(),
260 })
261 }
262}
263
264pub struct LessImpl<T> {
266 target: T,
267}
268
269impl<T> Operator<T> for LessImpl<T>
270where
271 T: core::cmp::Ord,
272{
273 fn apply(&self, value: &T) -> bool {
274 value < &self.target
275 }
276}
277
278pub struct Less;
280
281impl<T> OperatorClass<T> for Less
282where
283 T: Ord + FromStr,
284 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
285{
286 type Instance = LessImpl<T>;
287 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
288 Ok(LessImpl {
289 target: T::from_str(rhs).map_err(|e| FilterError::Instantiation(e.into()))?,
290 })
291 }
292}
293
294pub struct GreaterImpl<T> {
296 target: T,
297}
298
299impl<T> Operator<T> for GreaterImpl<T>
300where
301 T: core::cmp::Ord,
302{
303 fn apply(&self, value: &T) -> bool {
304 value > &self.target
305 }
306}
307
308pub struct Greater;
310
311impl<T> OperatorClass<T> for Greater
312where
313 T: Ord + FromStr,
314 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
315{
316 type Instance = GreaterImpl<T>;
317 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
318 Ok(GreaterImpl {
319 target: T::from_str(rhs).map_err(|e| FilterError::Instantiation(e.into()))?,
320 })
321 }
322}
323
324pub struct LessEqImpl<T> {
326 target: T,
327}
328
329impl<T> Operator<T> for LessEqImpl<T>
330where
331 T: core::cmp::Ord,
332{
333 fn apply(&self, value: &T) -> bool {
334 value <= &self.target
335 }
336}
337
338pub struct LessEq;
340
341impl<T> OperatorClass<T> for LessEq
342where
343 T: Ord + FromStr,
344 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
345{
346 type Instance = LessEqImpl<T>;
347 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
348 Ok(LessEqImpl {
349 target: T::from_str(rhs).map_err(|e| FilterError::Instantiation(e.into()))?,
350 })
351 }
352}
353
354pub struct GreaterEqImpl<T> {
356 target: T,
357}
358
359impl<T> Operator<T> for GreaterEqImpl<T>
360where
361 T: core::cmp::Ord,
362{
363 fn apply(&self, value: &T) -> bool {
364 value >= &self.target
365 }
366}
367
368pub struct GreaterEq;
370
371impl<T> OperatorClass<T> for GreaterEq
372where
373 T: Ord + FromStr,
374 <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
375{
376 type Instance = GreaterEqImpl<T>;
377 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
378 Ok(GreaterEqImpl {
379 target: T::from_str(rhs).map_err(|e| FilterError::Instantiation(e.into()))?,
380 })
381 }
382}
383
384pub struct IsNullImpl {
386 target: bool,
387}
388
389impl<T> Operator<T> for IsNullImpl {
390 fn apply(&self, _value: &T) -> bool {
391 !self.target
392 }
393 fn null_option(&self) -> bool {
394 self.target
395 }
396}
397
398pub struct IsNull;
400
401impl<T> OperatorClass<T> for IsNull {
402 type Instance = IsNullImpl;
403 fn instantiate(&self, rhs: &str) -> Result<Self::Instance, FilterError> {
404 Ok(IsNullImpl {
405 target: bool::from_str(rhs).map_err(|e| FilterError::Instantiation(e.into()))?,
406 })
407 }
408}