1 #[derive(Debug)]
2 pub enum Filter {
3     And(Vec<Filter>),
4     Or(Vec<Filter>),
5     Not(Box<Filter>),
6     Keyword(regex::Regex),
7 }
8 
9 impl Filter {
matches(&self, inp: &str) -> bool10     pub fn matches(&self, inp: &str) -> bool {
11         match self {
12             Filter::Keyword(regex) => regex.is_match(inp),
13             Filter::And(clauses) => clauses.iter().all(|clause| clause.matches(inp)),
14             Filter::Or(clauses) => clauses.iter().any(|clause| clause.matches(inp)),
15             Filter::Not(clause) => !clause.matches(inp),
16         }
17     }
18 }
19 
20 #[cfg(test)]
21 mod tests {
22     use super::*;
23     use crate::lang::Keyword;
24 
from_str(inp: &str) -> Filter25     pub fn from_str(inp: &str) -> Filter {
26         Filter::Keyword(Keyword::new_exact(inp.to_owned()).to_regex())
27     }
28 
29     #[test]
filter_and()30     fn filter_and() {
31         let filt = Filter::And(vec![from_str("abc"), from_str("cde")]);
32         assert_eq!(filt.matches("abc cde"), true);
33         assert_eq!(filt.matches("abc"), false);
34     }
35 
36     #[test]
filter_or()37     fn filter_or() {
38         let filt = Filter::Or(vec![from_str("abc"), from_str("cde")]);
39         assert_eq!(filt.matches("abc cde"), true);
40         assert_eq!(filt.matches("abc"), true);
41         assert_eq!(filt.matches("cde"), true);
42         assert_eq!(filt.matches("def"), false);
43     }
44 
45     #[test]
filter_wildcard()46     fn filter_wildcard() {
47         let filt = Filter::And(vec![]);
48         assert_eq!(filt.matches("abc"), true);
49     }
50 
51     #[test]
filter_not()52     fn filter_not() {
53         let filt = Filter::And(vec![from_str("abc"), from_str("cde")]);
54         let filt = Filter::Not(Box::new(filt));
55         assert_eq!(filt.matches("abc cde"), false);
56         assert_eq!(filt.matches("abc"), true);
57     }
58 
59     #[test]
filter_complex()60     fn filter_complex() {
61         let filt_letters = Filter::And(vec![from_str("abc"), from_str("cde")]);
62         let filt_numbers = Filter::And(vec![from_str("123"), from_str("456")]);
63         let filt = Filter::Or(vec![filt_letters, filt_numbers]);
64         assert_eq!(filt.matches("abc cde"), true);
65         assert_eq!(filt.matches("abc"), false);
66         assert_eq!(filt.matches("123 456"), true);
67         assert_eq!(filt.matches("123 cde"), false);
68     }
69 }
70