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