atomr_patterns/specification/
mod.rs1pub trait Specification<T>: Send + Sync {
22 fn is_satisfied_by(&self, t: &T) -> bool;
23
24 fn and<S>(self, other: S) -> AndSpec<Self, S>
25 where
26 Self: Sized,
27 S: Specification<T>,
28 {
29 AndSpec { a: self, b: other }
30 }
31
32 fn or<S>(self, other: S) -> OrSpec<Self, S>
33 where
34 Self: Sized,
35 S: Specification<T>,
36 {
37 OrSpec { a: self, b: other }
38 }
39
40 fn not(self) -> NotSpec<Self>
41 where
42 Self: Sized,
43 {
44 NotSpec { inner: self }
45 }
46}
47
48pub struct AndSpec<A, B> {
49 a: A,
50 b: B,
51}
52impl<T, A: Specification<T>, B: Specification<T>> Specification<T> for AndSpec<A, B> {
53 fn is_satisfied_by(&self, t: &T) -> bool {
54 self.a.is_satisfied_by(t) && self.b.is_satisfied_by(t)
55 }
56}
57
58pub struct OrSpec<A, B> {
59 a: A,
60 b: B,
61}
62impl<T, A: Specification<T>, B: Specification<T>> Specification<T> for OrSpec<A, B> {
63 fn is_satisfied_by(&self, t: &T) -> bool {
64 self.a.is_satisfied_by(t) || self.b.is_satisfied_by(t)
65 }
66}
67
68pub struct NotSpec<S> {
69 inner: S,
70}
71impl<T, S: Specification<T>> Specification<T> for NotSpec<S> {
72 fn is_satisfied_by(&self, t: &T) -> bool {
73 !self.inner.is_satisfied_by(t)
74 }
75}
76
77pub struct FnSpec<F>(pub F);
79impl<T, F: Fn(&T) -> bool + Send + Sync> Specification<T> for FnSpec<F> {
80 fn is_satisfied_by(&self, t: &T) -> bool {
81 (self.0)(t)
82 }
83}