1use crate::{rbe_error::RbeError, Pending};
2use crate::{Key, Ref, Value};
3use core::hash::Hash;
4use serde::{Deserialize, Serialize};
5use std::fmt::Debug;
6use std::fmt::{Display, Formatter};
7use std::hash::Hasher;
8
9#[derive(PartialEq, Eq, Hash, Clone, Serialize, Debug, Deserialize)]
12pub enum MatchCond<K, V, R>
13where
14 K: Key,
15 V: Value,
16 R: Ref,
17{
18 Single(SingleCond<K, V, R>),
19 Ref(R),
20 And(Vec<MatchCond<K, V, R>>),
21 }
24
25impl<K, V, R> MatchCond<K, V, R>
26where
27 K: Key,
28 V: Value,
29 R: Ref,
30{
31 pub fn new() -> MatchCond<K, V, R> {
32 MatchCond::Single(SingleCond::new())
33 }
34
35 pub fn empty() -> MatchCond<K, V, R> {
36 MatchCond::Single(SingleCond::new().with_name("empty"))
37 }
38
39 pub fn ref_(r: R) -> MatchCond<K, V, R> {
40 MatchCond::Ref(r)
41 }
42
43 pub fn matches(&self, value: &V) -> Result<Pending<V, R>, RbeError<K, V, R>> {
44 match self {
45 MatchCond::Single(single) => single.matches(value),
46 MatchCond::Ref(r) => Ok(Pending::from_pair(value.clone(), r.clone())),
47 _ => {
53 todo!()
54 }
55 }
56 }
57
58 pub fn single(single: SingleCond<K, V, R>) -> Self {
59 MatchCond::Single(single)
60 }
61
62 pub fn simple(
63 name: &str,
64 cond: impl Fn(&V) -> Result<Pending<V, R>, RbeError<K, V, R>> + Clone + 'static,
65 ) -> Self {
66 MatchCond::single(SingleCond::new().with_name(name).with_cond(cond))
67 }
68}
69
70impl<K, V, R> Display for MatchCond<K, V, R>
71where
72 K: Key,
73 V: Value,
74 R: Ref,
75{
76 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
77 match self {
78 MatchCond::Single(sc) => {
79 write!(f, "{sc}")?;
80 Ok(())
81 }
82 MatchCond::Ref(r) => {
83 write!(f, "@{r}")?;
84 Ok(())
85 }
86 MatchCond::And(cs) => {
87 write!(f, "And(")?;
88 cs.iter().try_fold((), |_, c| write!(f, "|{c}"))?;
89 write!(f, ")")
90 } }
97 }
98}
99
100impl<K, V, R> Default for MatchCond<K, V, R>
101where
102 K: Key,
103 V: Value,
104 R: Ref,
105{
106 fn default() -> Self {
107 MatchCond::Single(SingleCond::default())
108 }
109}
110
111#[derive(Serialize, Deserialize)]
113pub struct SingleCond<K, V, R>
114where
115 K: Hash + Eq + Display + Default,
116 V: Hash + Eq + Default + PartialEq + Clone,
117 R: Hash + Default + PartialEq + Clone,
118{
119 #[serde(skip_serializing_if = "Option::is_none")]
120 name: Option<String>,
121
122 #[serde(skip)]
123 cond: Vec<Box<dyn Cond<K, V, R>>>,
124}
125
126trait Cond<K, V, R>
131where
132 K: Key,
133 V: Value,
134 R: Ref,
135{
136 fn clone_box(&self) -> Box<dyn Cond<K, V, R>>;
137 fn call(&self, v: &V) -> Result<Pending<V, R>, RbeError<K, V, R>>;
138}
139
140impl<K, V, R, F> Cond<K, V, R> for F
141where
142 K: Key,
143 V: Value,
144 R: Ref,
145 F: 'static + Fn(&V) -> Result<Pending<V, R>, RbeError<K, V, R>> + Clone,
146{
147 fn clone_box(&self) -> Box<dyn Cond<K, V, R>> {
148 Box::new(self.clone())
149 }
150
151 fn call(&self, v: &V) -> Result<Pending<V, R>, RbeError<K, V, R>> {
152 self(v)
153 }
154}
155
156impl<K, V, R> Clone for Box<dyn Cond<K, V, R>>
157where
158 K: Key,
159 V: Value,
160 R: Ref,
161{
162 fn clone(&self) -> Self {
163 self.clone_box()
164 }
165}
166
167impl<K, V, R> Clone for SingleCond<K, V, R>
178where
179 K: Key,
180 V: Value,
181 R: Ref,
182{
183 fn clone(&self) -> Self {
184 SingleCond {
185 name: self.name.clone(),
186 cond: {
187 let mut r = Vec::new();
188 for c in self.cond.iter() {
189 r.push(c.clone())
190 }
191 r
192 }, }
202 }
203}
204
205impl<K, V, R> SingleCond<K, V, R>
206where
207 K: Key,
208 V: Value,
209 R: Ref,
210{
211 pub fn matches(&self, value: &V) -> Result<Pending<V, R>, RbeError<K, V, R>> {
212 self.cond.iter().try_fold(Pending::new(), |mut current, f| {
213 let pending = f.call(value)?;
214 current.merge(pending);
215 Ok(current)
216 })
217 }
218
219 pub fn new() -> SingleCond<K, V, R> {
220 SingleCond {
221 name: None,
222 cond: Vec::new(),
223 }
224 }
225
226 pub fn with_name(mut self, name: &str) -> Self {
227 self.name = Some(name.to_string());
228 self
229 }
230
231 pub fn with_cond(
232 mut self,
233 cond: impl Fn(&V) -> Result<Pending<V, R>, RbeError<K, V, R>> + Clone + 'static,
234 ) -> Self {
235 self.cond.push(Box::new(cond));
236 self
237 }
238
239 pub fn name(&self) -> String {
240 self.name.clone().unwrap_or_default()
241 }
242}
243
244impl<K, V, R> PartialEq for SingleCond<K, V, R>
245where
246 K: Key,
247 V: Value,
248 R: Ref,
249{
250 fn eq(&self, other: &Self) -> bool {
251 self.name == other.name
252 }
253}
254
255impl<K, V, R> Eq for SingleCond<K, V, R>
256where
257 K: Key,
258 V: Value,
259 R: Ref,
260{
261}
262
263impl<K, V, R> Hash for SingleCond<K, V, R>
264where
265 K: Key,
266 V: Value,
267 R: Ref,
268{
269 fn hash<H: Hasher>(&self, hasher: &mut H) {
270 self.name.hash(hasher)
271 }
272}
273
274impl<K, V, R> Default for SingleCond<K, V, R>
275where
276 K: Key,
277 V: Value,
278 R: Ref,
279{
280 fn default() -> Self {
281 SingleCond::new()
282 }
283}
284
285impl<K, V, R> Debug for SingleCond<K, V, R>
286where
287 K: Key,
288 V: Value,
289 R: Ref,
290{
291 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
292 write!(f, "{}", self.name.clone().unwrap_or_default())?;
293 Ok(())
294 }
295}
296
297impl<K, V, R> Display for SingleCond<K, V, R>
298where
299 K: Key,
300 V: Value,
301 R: Ref,
302{
303 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
304 write!(f, "{}", self.name.clone().unwrap_or_default())?;
305 Ok(())
306 }
307}
308
309#[cfg(test)]
310mod tests {
311 use super::*;
312
313 #[test]
314 fn test_even_cond_2_pass() {
315 let cond_even: SingleCond<char, i32, String> = SingleCond::new().with_cond(|v| {
316 if v % 2 == 0 {
317 Ok(Pending::new())
318 } else {
319 Err(RbeError::MsgError {
320 msg: format!("Value {v} is not even"),
321 })
322 }
323 });
324
325 assert_eq!(cond_even.matches(&2), Ok(Pending::new()));
326 }
327
328 #[test]
329 fn test_even_cond_3_fail() {
330 let cond_even: SingleCond<char, i32, String> = SingleCond::new().with_cond(|v| {
331 if v % 2 == 0 {
332 Ok(Pending::new())
333 } else {
334 Err(RbeError::MsgError {
335 msg: format!("Value {v} is not even"),
336 })
337 }
338 });
339
340 assert!(cond_even.matches(&3).is_err());
341 }
342
343 #[test]
344 fn test_name_fail() {
345 fn cond_name(name: String) -> SingleCond<char, String, String> {
346 SingleCond::new().with_cond(move |v: &String| {
347 if *v == name {
348 Ok(Pending::new())
349 } else {
350 Err(RbeError::MsgError {
351 msg: format!("Value {v} is not equal to {name}"),
352 })
353 }
354 })
355 }
356
357 assert!(cond_name("foo".to_string())
358 .matches(&"baz".to_string())
359 .is_err());
360 }
361
362 #[test]
363 fn test_name_pass() {
364 fn cond_name(name: String) -> SingleCond<char, String, String> {
365 SingleCond::new()
366 .with_name("name")
367 .with_cond(move |v: &String| {
368 if *v == name {
369 Ok(Pending::new())
370 } else {
371 Err(RbeError::MsgError {
372 msg: format!("Value {v} failed condition is not equal to {name}",),
373 })
374 }
375 })
376 }
377
378 assert_eq!(
379 cond_name("foo".to_string()).matches(&"foo".to_string()),
380 Ok(Pending::new())
381 );
382 }
383}