dm_database_parser_sqllog/
matcher.rs1use daachorse::DoubleArrayAhoCorasick;
2
3pub struct Matcher {
7 ac: DoubleArrayAhoCorasick<usize>,
8 patterns: Vec<String>,
9}
10
11impl Matcher {
12 pub fn from_patterns<S: AsRef<str>>(patterns: &[S]) -> Self {
15 let patterns_owned: Vec<String> = patterns
17 .iter()
18 .map(|s| s.as_ref().to_string())
19 .filter(|s| !s.is_empty())
20 .collect();
21
22 if patterns_owned.is_empty() {
23 panic!("failed to build daachorse automaton: no non-empty patterns provided");
24 }
25
26 let pats_bufs: Vec<Vec<u8>> = patterns_owned.iter().map(|s| s.as_bytes().to_vec()).collect();
28 let pats_slices: Vec<&[u8]> = pats_bufs.iter().map(|v| v.as_slice()).collect();
29
30 let ac = DoubleArrayAhoCorasick::new(&pats_slices)
31 .unwrap_or_else(|e| panic!("failed to build daachorse automaton: {}", e));
32
33 Matcher { ac, patterns: patterns_owned }
34 }
35
36 pub fn find_first_positions(&self, haystack: &[u8]) -> Vec<Option<usize>> {
39 let mut first: Vec<Option<usize>> = vec![None; self.patterns.len()];
40 for m in self.ac.find_iter(haystack) {
41 let id = m.value();
42 if id < first.len() && first[id].is_none() {
43 first[id] = Some(m.start());
44 }
45 }
46 first
47 }
48
49 pub fn patterns_len(&self) -> usize {
51 self.patterns.len()
52 }
53}