1use std::fmt;
12use std::marker::PhantomData;
13
14use crate::reflection;
15use crate::Predicate;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct AndPredicate<M1, M2, Item>
22where
23 M1: Predicate<Item>,
24 M2: Predicate<Item>,
25 Item: ?Sized,
26{
27 a: M1,
28 b: M2,
29 _phantom: PhantomData<Item>,
30}
31
32impl<M1, M2, Item> AndPredicate<M1, M2, Item>
33where
34 M1: Predicate<Item>,
35 M2: Predicate<Item>,
36 Item: ?Sized,
37{
38 pub fn new(a: M1, b: M2) -> AndPredicate<M1, M2, Item> {
40 AndPredicate {
41 a,
42 b,
43 _phantom: PhantomData,
44 }
45 }
46}
47
48impl<M1, M2, Item> Predicate<Item> for AndPredicate<M1, M2, Item>
49where
50 M1: Predicate<Item>,
51 M2: Predicate<Item>,
52 Item: ?Sized,
53{
54 fn eval(&self, item: &Item) -> bool {
55 self.a.eval(item) && self.b.eval(item)
56 }
57
58 fn find_case<'a>(&'a self, expected: bool, variable: &Item) -> Option<reflection::Case<'a>> {
59 let child_a = self.a.find_case(expected, variable);
60 match (expected, child_a) {
61 (true, Some(child_a)) => self.b.find_case(expected, variable).map(|child_b| {
62 reflection::Case::new(Some(self), expected)
63 .add_child(child_a)
64 .add_child(child_b)
65 }),
66 (true, None) => None,
67 (false, Some(child_a)) => {
68 Some(reflection::Case::new(Some(self), expected).add_child(child_a))
69 }
70 (false, None) => self
71 .b
72 .find_case(expected, variable)
73 .map(|child_b| reflection::Case::new(Some(self), expected).add_child(child_b)),
74 }
75 }
76}
77
78impl<M1, M2, Item> reflection::PredicateReflection for AndPredicate<M1, M2, Item>
79where
80 M1: Predicate<Item>,
81 M2: Predicate<Item>,
82 Item: ?Sized,
83{
84 fn children<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Child<'a>> + 'a> {
85 let params = vec![
86 reflection::Child::new("left", &self.a),
87 reflection::Child::new("right", &self.b),
88 ];
89 Box::new(params.into_iter())
90 }
91}
92
93impl<M1, M2, Item> fmt::Display for AndPredicate<M1, M2, Item>
94where
95 M1: Predicate<Item>,
96 M2: Predicate<Item>,
97 Item: ?Sized,
98{
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 write!(f, "({} && {})", self.a, self.b)
101 }
102}
103
104#[cfg(test)]
105mod test_and {
106 use crate::prelude::*;
107
108 #[test]
109 fn find_case_true() {
110 assert!(predicate::always()
111 .and(predicate::always())
112 .find_case(true, &5)
113 .is_some());
114 }
115
116 #[test]
117 fn find_case_true_left_fail() {
118 assert!(predicate::never()
119 .and(predicate::always())
120 .find_case(true, &5)
121 .is_none());
122 }
123
124 #[test]
125 fn find_case_true_right_fail() {
126 assert!(predicate::always()
127 .and(predicate::never())
128 .find_case(true, &5)
129 .is_none());
130 }
131
132 #[test]
133 fn find_case_true_fails() {
134 assert!(predicate::never()
135 .and(predicate::never())
136 .find_case(true, &5)
137 .is_none());
138 }
139
140 #[test]
141 fn find_case_false() {
142 assert!(predicate::never()
143 .and(predicate::never())
144 .find_case(false, &5)
145 .is_some());
146 }
147
148 #[test]
149 fn find_case_false_fails() {
150 assert!(predicate::always()
151 .and(predicate::always())
152 .find_case(false, &5)
153 .is_none());
154 }
155
156 #[test]
157 fn find_case_false_left_fail() {
158 assert!(predicate::never()
159 .and(predicate::always())
160 .find_case(false, &5)
161 .is_some());
162 }
163
164 #[test]
165 fn find_case_false_right_fail() {
166 assert!(predicate::always()
167 .and(predicate::never())
168 .find_case(false, &5)
169 .is_some());
170 }
171}
172
173#[derive(Debug, Clone, Copy, PartialEq, Eq)]
177pub struct OrPredicate<M1, M2, Item>
178where
179 M1: Predicate<Item>,
180 M2: Predicate<Item>,
181 Item: ?Sized,
182{
183 a: M1,
184 b: M2,
185 _phantom: PhantomData<Item>,
186}
187
188impl<M1, M2, Item> OrPredicate<M1, M2, Item>
189where
190 M1: Predicate<Item>,
191 M2: Predicate<Item>,
192 Item: ?Sized,
193{
194 pub fn new(a: M1, b: M2) -> OrPredicate<M1, M2, Item> {
196 OrPredicate {
197 a,
198 b,
199 _phantom: PhantomData,
200 }
201 }
202}
203
204impl<M1, M2, Item> Predicate<Item> for OrPredicate<M1, M2, Item>
205where
206 M1: Predicate<Item>,
207 M2: Predicate<Item>,
208 Item: ?Sized,
209{
210 fn eval(&self, item: &Item) -> bool {
211 self.a.eval(item) || self.b.eval(item)
212 }
213
214 fn find_case<'a>(&'a self, expected: bool, variable: &Item) -> Option<reflection::Case<'a>> {
215 let child_a = self.a.find_case(expected, variable);
216 match (expected, child_a) {
217 (true, Some(child_a)) => {
218 Some(reflection::Case::new(Some(self), expected).add_child(child_a))
219 }
220 (true, None) => self
221 .b
222 .find_case(expected, variable)
223 .map(|child_b| reflection::Case::new(Some(self), expected).add_child(child_b)),
224 (false, Some(child_a)) => self.b.find_case(expected, variable).map(|child_b| {
225 reflection::Case::new(Some(self), expected)
226 .add_child(child_a)
227 .add_child(child_b)
228 }),
229 (false, None) => None,
230 }
231 }
232}
233
234impl<M1, M2, Item> reflection::PredicateReflection for OrPredicate<M1, M2, Item>
235where
236 M1: Predicate<Item>,
237 M2: Predicate<Item>,
238 Item: ?Sized,
239{
240 fn children<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Child<'a>> + 'a> {
241 let params = vec![
242 reflection::Child::new("left", &self.a),
243 reflection::Child::new("right", &self.b),
244 ];
245 Box::new(params.into_iter())
246 }
247}
248
249impl<M1, M2, Item> fmt::Display for OrPredicate<M1, M2, Item>
250where
251 M1: Predicate<Item>,
252 M2: Predicate<Item>,
253 Item: ?Sized,
254{
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 write!(f, "({} || {})", self.a, self.b)
257 }
258}
259
260#[cfg(test)]
261mod test_or {
262 use crate::prelude::*;
263
264 #[test]
265 fn find_case_true() {
266 assert!(predicate::always()
267 .or(predicate::always())
268 .find_case(true, &5)
269 .is_some());
270 }
271
272 #[test]
273 fn find_case_true_left_fail() {
274 assert!(predicate::never()
275 .or(predicate::always())
276 .find_case(true, &5)
277 .is_some());
278 }
279
280 #[test]
281 fn find_case_true_right_fail() {
282 assert!(predicate::always()
283 .or(predicate::never())
284 .find_case(true, &5)
285 .is_some());
286 }
287
288 #[test]
289 fn find_case_true_fails() {
290 assert!(predicate::never()
291 .or(predicate::never())
292 .find_case(true, &5)
293 .is_none());
294 }
295
296 #[test]
297 fn find_case_false() {
298 assert!(predicate::never()
299 .or(predicate::never())
300 .find_case(false, &5)
301 .is_some());
302 }
303
304 #[test]
305 fn find_case_false_fails() {
306 assert!(predicate::always()
307 .or(predicate::always())
308 .find_case(false, &5)
309 .is_none());
310 }
311
312 #[test]
313 fn find_case_false_left_fail() {
314 assert!(predicate::never()
315 .or(predicate::always())
316 .find_case(false, &5)
317 .is_none());
318 }
319
320 #[test]
321 fn find_case_false_right_fail() {
322 assert!(predicate::always()
323 .or(predicate::never())
324 .find_case(false, &5)
325 .is_none());
326 }
327}
328
329#[derive(Debug, Clone, Copy, PartialEq, Eq)]
333pub struct NotPredicate<M, Item>
334where
335 M: Predicate<Item>,
336 Item: ?Sized,
337{
338 inner: M,
339 _phantom: PhantomData<Item>,
340}
341
342impl<M, Item> NotPredicate<M, Item>
343where
344 M: Predicate<Item>,
345 Item: ?Sized,
346{
347 pub fn new(inner: M) -> NotPredicate<M, Item> {
349 NotPredicate {
350 inner,
351 _phantom: PhantomData,
352 }
353 }
354}
355
356impl<M, Item> Predicate<Item> for NotPredicate<M, Item>
357where
358 M: Predicate<Item>,
359 Item: ?Sized,
360{
361 fn eval(&self, item: &Item) -> bool {
362 !self.inner.eval(item)
363 }
364
365 fn find_case<'a>(&'a self, expected: bool, variable: &Item) -> Option<reflection::Case<'a>> {
366 self.inner
367 .find_case(!expected, variable)
368 .map(|child| reflection::Case::new(Some(self), expected).add_child(child))
369 }
370}
371
372impl<M, Item> reflection::PredicateReflection for NotPredicate<M, Item>
373where
374 M: Predicate<Item>,
375 Item: ?Sized,
376{
377 fn children<'a>(&'a self) -> Box<dyn Iterator<Item = reflection::Child<'a>> + 'a> {
378 let params = vec![reflection::Child::new("predicate", &self.inner)];
379 Box::new(params.into_iter())
380 }
381}
382
383impl<M, Item> fmt::Display for NotPredicate<M, Item>
384where
385 M: Predicate<Item>,
386 Item: ?Sized,
387{
388 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389 write!(f, "(! {})", self.inner)
390 }
391}
392
393pub trait PredicateBooleanExt<Item: ?Sized>
395where
396 Self: Predicate<Item>,
397{
398 fn and<B>(self, other: B) -> AndPredicate<Self, B, Item>
410 where
411 B: Predicate<Item>,
412 Self: Sized,
413 {
414 AndPredicate::new(self, other)
415 }
416
417 fn or<B>(self, other: B) -> OrPredicate<Self, B, Item>
431 where
432 B: Predicate<Item>,
433 Self: Sized,
434 {
435 OrPredicate::new(self, other)
436 }
437
438 fn not(self) -> NotPredicate<Self, Item>
450 where
451 Self: Sized,
452 {
453 NotPredicate::new(self)
454 }
455}
456
457impl<P, Item> PredicateBooleanExt<Item> for P
458where
459 P: Predicate<Item>,
460 Item: ?Sized,
461{
462}