1 //! A type that represents the union of a set of regular expressions. 2 3 use regex::RegexSet as RxSet; 4 5 // Yeah, I'm aware this is sorta crappy, should be cheaper to compile a regex 6 // ORing all the patterns, I guess... 7 8 /// A dynamic set of regular expressions. 9 #[derive(Debug)] 10 pub struct RegexSet { 11 items: Vec<String>, 12 set: Option<RxSet>, 13 } 14 15 impl RegexSet { 16 /// Is this set empty? is_empty(&self) -> bool17 pub fn is_empty(&self) -> bool { 18 self.items.is_empty() 19 } 20 21 /// Insert a new regex into this set. insert<S>(&mut self, string: S) where S: AsRef<str>,22 pub fn insert<S>(&mut self, string: S) 23 where 24 S: AsRef<str>, 25 { 26 self.items.push(format!("^{}$", string.as_ref())); 27 self.set = None; 28 } 29 30 /// Returns slice of String from its field 'items' get_items(&self) -> &[String]31 pub fn get_items(&self) -> &[String] { 32 &self.items[..] 33 } 34 35 /// Construct a RegexSet from the set of entries we've accumulated. 36 /// 37 /// Must be called before calling `matches()`, or it will always return 38 /// false. build(&mut self)39 pub fn build(&mut self) { 40 self.set = match RxSet::new(&self.items) { 41 Ok(x) => Some(x), 42 Err(e) => { 43 error!("Invalid regex in {:?}: {:?}", self.items, e); 44 None 45 } 46 } 47 } 48 49 /// Does the given `string` match any of the regexes in this set? matches<S>(&self, string: S) -> bool where S: AsRef<str>,50 pub fn matches<S>(&self, string: S) -> bool 51 where 52 S: AsRef<str>, 53 { 54 let s = string.as_ref(); 55 self.set.as_ref().map(|set| set.is_match(s)).unwrap_or( 56 false, 57 ) 58 } 59 } 60 61 impl Default for RegexSet { default() -> Self62 fn default() -> Self { 63 RegexSet { 64 items: vec![], 65 set: None, 66 } 67 } 68 } 69