text_reader/detector.rs
1use std::ffi::OsStr;
2
3use crate::TextReader;
4
5/// Text reader detector
6///
7/// # Examples
8///
9/// ```rust
10/// use text_reader::TextReader;
11/// use text_reader::Detector;
12///
13/// let text = r#""typeA""#;
14/// let mut reader = TextReader::new(text);
15/// let mut rets = Vec::new();
16/// while reader.has_next() {
17/// match reader.next() {
18/// Some('"') => {
19/// let mut detector = reader.detector();
20/// rets.push('"');
21/// if detector.next_text("type").yes() {
22/// detector.rollback();
23/// rets.push('t');
24/// }
25/// continue;
26/// }
27/// Some(ch) => {
28/// rets.push(ch);
29/// continue;
30/// }
31/// None => {}
32/// }
33/// }
34/// let ret = rets.iter().collect::<String>();
35/// println!("{}", ret); // "ttypeA"
36/// ```
37#[derive(Debug)]
38pub struct Detector<'a> {
39 reader: &'a mut TextReader,
40 compares: Vec<char>,
41 last_len: usize,
42}
43
44impl<'a> Detector<'a> {
45
46 /// Create detector
47 ///
48 /// # Examples
49 ///
50 /// ```rust
51 /// use text_reader::TextReader;
52 ///
53 /// let mut reader = TextReader::new("abc");
54 /// ```
55 pub fn new(reader: &'a mut TextReader) -> Self {
56 Self { reader, compares: Vec::new(), last_len: 0 }
57 }
58
59 /// Detect next char
60 ///
61 /// # Examples
62 ///
63 /// ```rust
64 /// use text_reader::TextReader;
65 ///
66 /// let mut reader = TextReader::new("abc");
67 /// let mut detector = reader.detector();
68 /// detector.next_char('a');
69 /// ```
70 pub fn next_char(&mut self, ch: char) -> &mut Self {
71 self.compares.push(ch);
72 self
73 }
74
75 /// Detect next string
76 ///
77 /// # Examples
78 ///
79 /// ```rust
80 /// use text_reader::TextReader;
81 ///
82 /// let mut reader = TextReader::new("abc");
83 /// let mut detector = reader.detector();
84 /// detector.next_text("ab");
85 /// ```
86 pub fn next_text<S: AsRef<OsStr>>(&mut self, text: S) -> &mut Self {
87 text.as_ref().to_str().unwrap().chars().collect::<Vec<char>>()
88 .iter()
89 .for_each(|ch| { self.next_char(ch.clone()); });
90 self
91 }
92
93 /// Detect result is true
94 ///
95 /// # Examples
96 ///
97 /// ```rust
98 /// use text_reader::TextReader;
99 ///
100 /// let mut vec = Vec::new();
101 /// let mut reader = TextReader::new("abc");
102 ///
103 /// while reader.has_next() {
104 /// match reader.next() {
105 /// Some(ch) => {
106 /// let mut detector = reader.detector();
107 /// if detector.next_text("bc").yes() {
108 /// println!("Detect ab");
109 /// }
110 /// vec.push(ch);
111 /// },
112 /// None => {}
113 /// }
114 /// }
115 /// println!("{}", vec.iter().collect::<String>()); // a
116 /// ```
117 pub fn yes(&mut self) -> bool {
118 self.detect()
119 }
120
121 /// Detect result is false
122 pub fn no(&mut self) -> bool {
123 !self.detect()
124 }
125
126 /// Rollback detector
127 /// If detect success detector not back position. if want, use rollback function to reset reader position
128 ///
129 /// # Examples
130 ///
131 /// ```rust
132 /// use text_reader::TextReader;
133 ///
134 /// let mut vec = Vec::new();
135 ///
136 /// let mut reader = TextReader::new("abc");
137 /// while reader.has_next() {
138 /// match reader.next() {
139 /// Some(ch) => {
140 /// let mut detector = reader.detector();
141 /// if detector.next_text("bc").yes() {
142 /// detector.rollback();
143 /// println!("Detect ab");
144 /// }
145 /// vec.push(ch);
146 /// },
147 /// None => {}
148 /// }
149 /// }
150 /// println!("{}", vec.iter().collect::<String>()); // abc
151 /// ```
152 pub fn rollback(&mut self) -> &mut Self {
153 for _ in 0..self.last_len {
154 self.reader.back();
155 }
156 self
157 }
158
159 fn detect(&mut self) -> bool {
160 let mut ix = 0;
161 let len = self.compares.len();
162
163 while self.reader.has_next() {
164 match self.reader.next() {
165 Some(ch) => {
166 let compare = match self.compares.get(ix) {
167 Some(c) => c.clone(),
168 None => {
169 self.reader.back();
170 self.last_len = len;
171 return true;
172 }
173 };
174 if ch != compare {
175 self.restore(ix + 1);
176 return false;
177 }
178 ix += 1;
179 }
180 None => {
181 self.restore(ix);
182 return false;
183 }
184 }
185 }
186 let same = ix == len;
187 if !same {
188 self.restore(ix);
189 } else {
190 self.last_len = len;
191 }
192 same
193 }
194
195 fn restore(&mut self, count: usize) -> &mut Self {
196 if count == 0 {
197 return self;
198 }
199 for _ in 0..count {
200 self.reader.back();
201 }
202 self
203 }
204}
205