1use std::fmt;
12
13use crate::reflection;
14use crate::utils;
15use crate::Predicate;
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18enum EqOps {
19 Equal,
20 NotEqual,
21}
22
23impl fmt::Display for EqOps {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 let op = match *self {
26 EqOps::Equal => "==",
27 EqOps::NotEqual => "!=",
28 };
29 write!(f, "{}", op)
30 }
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct EqPredicate<T>
39where
40 T: fmt::Debug + PartialEq,
41{
42 constant: T,
43 op: EqOps,
44}
45
46impl<T> Predicate<T> for EqPredicate<T>
47where
48 T: fmt::Debug + PartialEq,
49{
50 fn eval(&self, variable: &T) -> bool {
51 match self.op {
52 EqOps::Equal => variable.eq(&self.constant),
53 EqOps::NotEqual => variable.ne(&self.constant),
54 }
55 }
56
57 fn find_case<'a>(&'a self, expected: bool, variable: &T) -> Option<reflection::Case<'a>> {
58 utils::default_find_case(self, expected, variable)
59 }
60}
61
62impl<'a, T> Predicate<T> for EqPredicate<&'a T>
63where
64 T: fmt::Debug + PartialEq + ?Sized,
65{
66 fn eval(&self, variable: &T) -> bool {
67 match self.op {
68 EqOps::Equal => variable.eq(self.constant),
69 EqOps::NotEqual => variable.ne(self.constant),
70 }
71 }
72
73 fn find_case<'b>(&'b self, expected: bool, variable: &T) -> Option<reflection::Case<'b>> {
74 utils::default_find_case(self, expected, variable)
75 }
76}
77
78impl<T> reflection::PredicateReflection for EqPredicate<T> where T: fmt::Debug + PartialEq {}
79
80impl<T> fmt::Display for EqPredicate<T>
81where
82 T: fmt::Debug + PartialEq,
83{
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 write!(f, "var {} {:?}", self.op, self.constant)
86 }
87}
88
89pub fn eq<T>(constant: T) -> EqPredicate<T>
106where
107 T: fmt::Debug + PartialEq,
108{
109 EqPredicate {
110 constant,
111 op: EqOps::Equal,
112 }
113}
114
115pub fn ne<T>(constant: T) -> EqPredicate<T>
128where
129 T: PartialEq + fmt::Debug,
130{
131 EqPredicate {
132 constant,
133 op: EqOps::NotEqual,
134 }
135}
136
137#[derive(Clone, Copy, Debug, PartialEq, Eq)]
138enum OrdOps {
139 LessThan,
140 LessThanOrEqual,
141 GreaterThanOrEqual,
142 GreaterThan,
143}
144
145impl fmt::Display for OrdOps {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 let op = match *self {
148 OrdOps::LessThan => "<",
149 OrdOps::LessThanOrEqual => "<=",
150 OrdOps::GreaterThanOrEqual => ">=",
151 OrdOps::GreaterThan => ">",
152 };
153 write!(f, "{}", op)
154 }
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq)]
162pub struct OrdPredicate<T>
163where
164 T: fmt::Debug + PartialOrd,
165{
166 constant: T,
167 op: OrdOps,
168}
169
170impl<T> Predicate<T> for OrdPredicate<T>
171where
172 T: fmt::Debug + PartialOrd,
173{
174 fn eval(&self, variable: &T) -> bool {
175 match self.op {
176 OrdOps::LessThan => variable.lt(&self.constant),
177 OrdOps::LessThanOrEqual => variable.le(&self.constant),
178 OrdOps::GreaterThanOrEqual => variable.ge(&self.constant),
179 OrdOps::GreaterThan => variable.gt(&self.constant),
180 }
181 }
182
183 fn find_case<'a>(&'a self, expected: bool, variable: &T) -> Option<reflection::Case<'a>> {
184 utils::default_find_case(self, expected, variable)
185 }
186}
187
188impl<'a, T> Predicate<T> for OrdPredicate<&'a T>
189where
190 T: fmt::Debug + PartialOrd + ?Sized,
191{
192 fn eval(&self, variable: &T) -> bool {
193 match self.op {
194 OrdOps::LessThan => variable.lt(self.constant),
195 OrdOps::LessThanOrEqual => variable.le(self.constant),
196 OrdOps::GreaterThanOrEqual => variable.ge(self.constant),
197 OrdOps::GreaterThan => variable.gt(self.constant),
198 }
199 }
200
201 fn find_case<'b>(&'b self, expected: bool, variable: &T) -> Option<reflection::Case<'b>> {
202 utils::default_find_case(self, expected, variable)
203 }
204}
205
206impl<T> reflection::PredicateReflection for OrdPredicate<T> where T: fmt::Debug + PartialOrd {}
207
208impl<T> fmt::Display for OrdPredicate<T>
209where
210 T: fmt::Debug + PartialOrd,
211{
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 write!(f, "var {} {:?}", self.op, self.constant)
214 }
215}
216
217pub fn lt<T>(constant: T) -> OrdPredicate<T>
234where
235 T: fmt::Debug + PartialOrd,
236{
237 OrdPredicate {
238 constant,
239 op: OrdOps::LessThan,
240 }
241}
242
243pub fn le<T>(constant: T) -> OrdPredicate<T>
257where
258 T: PartialOrd + fmt::Debug,
259{
260 OrdPredicate {
261 constant,
262 op: OrdOps::LessThanOrEqual,
263 }
264}
265
266pub fn ge<T>(constant: T) -> OrdPredicate<T>
280where
281 T: PartialOrd + fmt::Debug,
282{
283 OrdPredicate {
284 constant,
285 op: OrdOps::GreaterThanOrEqual,
286 }
287}
288
289pub fn gt<T>(constant: T) -> OrdPredicate<T>
303where
304 T: PartialOrd + fmt::Debug,
305{
306 OrdPredicate {
307 constant,
308 op: OrdOps::GreaterThan,
309 }
310}