Skip to main content

string_patterns/
pattern_filter.rs

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