string_patterns/
pattern_filter.rs

1use crate::{build_regex, utils::build_whole_word_pattern};
2
3/// Trait with methods to filter arrays or vectors of strings by regular expression patterns
4/// Only pattern_filter() method needs to be implemented.
5/// Both implementations ensure the regex is compiled only once.
6/// If the regex fails, filters will not be applied.
7pub trait PatternFilter<'a, T> where T:Sized {
8  /// Filter an array of strs by the pattern
9  fn pattern_filter(&'a self, pattern: &str, case_insensitive: bool) -> Vec<T>;
10
11  /// Filters strings in case-insensitive mode
12  fn pattern_filter_ci(&'a self, pattern: &str) -> Vec<T> {
13    self.pattern_filter(pattern, true)
14  }
15
16  /// Filters strings in case-sensitive mode
17  fn pattern_filter_cs(&'a self, pattern: &str) -> Vec<T> {
18    self.pattern_filter(pattern, false)
19  }
20
21  /// Filters strings by whole word regex patterns with case-insensitive flag
22  fn pattern_filter_word(&'a self, pattern: &str, case_insensitive: bool) -> Vec<T> {
23    let word_pattern = build_whole_word_pattern(pattern);
24    self.pattern_filter(&word_pattern, case_insensitive)
25  }
26
27  /// Filters strings by whole word regex patterns in case-insensitive mode
28  fn pattern_filter_word_ci(&'a self, pattern: &str) -> Vec<T> {
29    self.pattern_filter_word(pattern, true)
30  }
31
32  /// Filters strings by whole word regex patterns in case-sensitive mode
33  fn pattern_filter_word_cs(&'a self, pattern: &str) -> Vec<T> {
34    self.pattern_filter_word(pattern, false)
35  }
36}
37
38impl<'a> PatternFilter<'a, String> for [String] {
39  /// Filter an array of strs by the pattern
40  fn pattern_filter(&'a self, pattern: &str, case_insensitive: bool) -> Vec<String> {
41    if let Ok(re) = build_regex(pattern, case_insensitive) {
42      self.into_iter().filter(|s| re.is_match(s)).map(|s| s.to_owned()).collect::<Vec<String>>()
43    } else {
44      self.to_owned()
45    }
46  }
47}
48
49impl<'a> PatternFilter<'a, &'a str> for [&str] {
50  /// Filter an array of strs by the pattern
51  fn pattern_filter(&'a self, pattern: &str, case_insensitive: bool) -> Vec<&str> {
52    if let Ok(re) = build_regex(pattern, case_insensitive) {
53      self.into_iter().filter(|s| re.is_match(s)).map(|s| s.to_owned()).collect::<Vec<&str>>()
54    } else {
55      self.into_iter().map(|s| s.to_owned()).collect::<Vec<&str>>()
56    }
57  }
58}