pattern_recognizer.rs - icy_draw - [fork] icy_draw is the successor to mystic draw.
HTML git clone https://git.drkhsh.at/icy_draw.git
DIR Log
DIR Files
DIR Refs
DIR README
---
pattern_recognizer.rs (2494B)
---
1 pub struct PatternRecognizer {
2 pattern: Vec<u8>,
3 cur_idx: usize,
4 ignore_case: bool,
5 }
6
7 impl PatternRecognizer {
8 pub fn from(data: &[u8], ignore_case: bool) -> Self {
9 Self {
10 pattern: if ignore_case {
11 data.iter().map(|c| (*c).to_ascii_uppercase()).collect()
12 } else {
13 data.to_vec()
14 },
15 cur_idx: 0,
16 ignore_case,
17 }
18 }
19
20 pub fn _reset(&mut self) {
21 self.cur_idx = 0;
22 }
23
24 pub fn push_ch(&mut self, ch: u8) -> bool {
25 let p = self.pattern[self.cur_idx];
26 if p == ch || self.ignore_case && ch.is_ascii_lowercase() && ch - b'a' + b'A' == p {
27 self.cur_idx += 1;
28 if self.cur_idx >= self.pattern.len() {
29 self.cur_idx = 0;
30 return true;
31 }
32 } else if self.cur_idx > 0 {
33 self.cur_idx = 0;
34 return self.push_ch(ch);
35 }
36 false
37 }
38 }
39
40 #[cfg(test)]
41 mod tests {
42 use super::PatternRecognizer;
43
44 #[test]
45 fn test_pattern_recognizer() {
46 let mut test = PatternRecognizer::from(b"Name", false);
47
48 let mut result = false;
49 for b in b"Name" {
50 result = test.push_ch(*b);
51 }
52 assert!(result);
53
54 let mut result = false;
55 for b in b"name" {
56 result = test.push_ch(*b);
57 }
58 assert!(!result);
59 }
60
61 #[test]
62 fn test_pattern_recognizer_ignore_case() {
63 let mut test = PatternRecognizer::from(b"Name", true);
64
65 let mut result = false;
66 for b in b"name" {
67 result = test.push_ch(*b);
68 }
69 assert!(result);
70
71 let mut result = false;
72 for b in b"NaMe" {
73 result = test.push_ch(*b);
74 }
75 assert!(result);
76
77 let mut result = false;
78 for b in b"Nmae" {
79 result = test.push_ch(*b);
80 }
81 assert!(!result);
82 }
83
84 #[test]
85 fn test_pattern_recognizer_recovery() {
86 let mut test = PatternRecognizer::from(b"name", false);
87
88 let mut result = false;
89 for b in b"namname" {
90 result = test.push_ch(*b);
91 }
92 assert!(result);
93 }
94
95 #[test]
96 fn test_pattern_recognizer_invalid() {
97 let mut test = PatternRecognizer::from(b"name", false);
98
99 let mut result = false;
100 for b in b"n_a_m_e" {
101 result = test.push_ch(*b);
102 }
103 assert!(!result);
104 }
105 }