1use self::StartsWithStateInternal::*;
2
3pub trait Automaton {
25 type State;
27
28 fn start(&self) -> Self::State;
33
34 fn is_match(&self, state: &Self::State) -> bool;
36
37 fn can_match(&self, _state: &Self::State) -> bool {
47 true
48 }
49
50 fn will_always_match(&self, _state: &Self::State) -> bool {
61 false
62 }
63
64 fn accept(&self, state: &Self::State, byte: u8) -> Self::State;
66
67 fn starts_with(self) -> StartsWith<Self>
70 where
71 Self: Sized,
72 {
73 StartsWith(self)
74 }
75
76 fn union<Rhs: Automaton>(self, rhs: Rhs) -> Union<Self, Rhs>
79 where
80 Self: Sized,
81 {
82 Union(self, rhs)
83 }
84
85 fn intersection<Rhs: Automaton>(self, rhs: Rhs) -> Intersection<Self, Rhs>
88 where
89 Self: Sized,
90 {
91 Intersection(self, rhs)
92 }
93
94 fn complement(self) -> Complement<Self>
97 where
98 Self: Sized,
99 {
100 Complement(self)
101 }
102}
103
104impl<'a, T: Automaton> Automaton for &'a T {
105 type State = T::State;
106
107 fn start(&self) -> Self::State {
108 (*self).start()
109 }
110
111 fn is_match(&self, state: &Self::State) -> bool {
112 (*self).is_match(state)
113 }
114
115 fn can_match(&self, state: &Self::State) -> bool {
116 (*self).can_match(state)
117 }
118
119 fn will_always_match(&self, state: &Self::State) -> bool {
120 (*self).will_always_match(state)
121 }
122
123 fn accept(&self, state: &Self::State, byte: u8) -> Self::State {
124 (*self).accept(state, byte)
125 }
126}
127
128#[derive(Clone, Debug)]
130pub struct Subsequence<'a> {
131 subseq: &'a [u8],
132}
133
134impl<'a> Subsequence<'a> {
135 #[inline]
138 pub fn new(subsequence: &'a str) -> Subsequence<'a> {
139 Subsequence {
140 subseq: subsequence.as_bytes(),
141 }
142 }
143}
144
145impl<'a> Automaton for Subsequence<'a> {
146 type State = usize;
147
148 #[inline]
149 fn start(&self) -> usize {
150 0
151 }
152
153 #[inline]
154 fn is_match(&self, &state: &usize) -> bool {
155 state == self.subseq.len()
156 }
157
158 #[inline]
159 fn can_match(&self, _: &usize) -> bool {
160 true
161 }
162
163 #[inline]
164 fn will_always_match(&self, &state: &usize) -> bool {
165 state == self.subseq.len()
166 }
167
168 #[inline]
169 fn accept(&self, &state: &usize, byte: u8) -> usize {
170 if state == self.subseq.len() {
171 return state;
172 }
173 state + (byte == self.subseq[state]) as usize
174 }
175}
176
177#[derive(Clone, Debug)]
182pub struct AlwaysMatch;
183
184impl Automaton for AlwaysMatch {
185 type State = ();
186
187 #[inline]
188 fn start(&self) {}
189 #[inline]
190 fn is_match(&self, _: &()) -> bool {
191 true
192 }
193 #[inline]
194 fn can_match(&self, _: &()) -> bool {
195 true
196 }
197 #[inline]
198 fn will_always_match(&self, _: &()) -> bool {
199 true
200 }
201 #[inline]
202 fn accept(&self, _: &(), _: u8) {}
203}
204
205#[derive(Clone, Debug)]
208pub struct StartsWith<A>(A);
209
210pub struct StartsWithState<A: Automaton>(StartsWithStateInternal<A>);
212
213enum StartsWithStateInternal<A: Automaton> {
214 Done,
215 Running(A::State),
216}
217
218impl<A: Automaton> Automaton for StartsWith<A> {
219 type State = StartsWithState<A>;
220
221 fn start(&self) -> StartsWithState<A> {
222 StartsWithState({
223 let inner = self.0.start();
224 if self.0.is_match(&inner) {
225 Done
226 } else {
227 Running(inner)
228 }
229 })
230 }
231
232 fn is_match(&self, state: &StartsWithState<A>) -> bool {
233 match state.0 {
234 Done => true,
235 Running(_) => false,
236 }
237 }
238
239 fn can_match(&self, state: &StartsWithState<A>) -> bool {
240 match state.0 {
241 Done => true,
242 Running(ref inner) => self.0.can_match(inner),
243 }
244 }
245
246 fn will_always_match(&self, state: &StartsWithState<A>) -> bool {
247 match state.0 {
248 Done => true,
249 Running(_) => false,
250 }
251 }
252
253 fn accept(&self, state: &StartsWithState<A>, byte: u8) -> StartsWithState<A> {
254 StartsWithState(match state.0 {
255 Done => Done,
256 Running(ref inner) => {
257 let next_inner = self.0.accept(inner, byte);
258 if self.0.is_match(&next_inner) {
259 Done
260 } else {
261 Running(next_inner)
262 }
263 }
264 })
265 }
266}
267
268#[derive(Clone, Debug)]
270pub struct Union<A, B>(A, B);
271
272pub struct UnionState<A: Automaton, B: Automaton>(A::State, B::State);
274
275impl<A: Automaton, B: Automaton> Automaton for Union<A, B> {
276 type State = UnionState<A, B>;
277
278 fn start(&self) -> UnionState<A, B> {
279 UnionState(self.0.start(), self.1.start())
280 }
281
282 fn is_match(&self, state: &UnionState<A, B>) -> bool {
283 self.0.is_match(&state.0) || self.1.is_match(&state.1)
284 }
285
286 fn can_match(&self, state: &UnionState<A, B>) -> bool {
287 self.0.can_match(&state.0) || self.1.can_match(&state.1)
288 }
289
290 fn will_always_match(&self, state: &UnionState<A, B>) -> bool {
291 self.0.will_always_match(&state.0) || self.1.will_always_match(&state.1)
292 }
293
294 fn accept(&self, state: &UnionState<A, B>, byte: u8) -> UnionState<A, B> {
295 UnionState(self.0.accept(&state.0, byte), self.1.accept(&state.1, byte))
296 }
297}
298
299#[derive(Clone, Debug)]
301pub struct Intersection<A, B>(A, B);
302
303pub struct IntersectionState<A: Automaton, B: Automaton>(A::State, B::State);
305
306impl<A: Automaton, B: Automaton> Automaton for Intersection<A, B> {
307 type State = IntersectionState<A, B>;
308
309 fn start(&self) -> IntersectionState<A, B> {
310 IntersectionState(self.0.start(), self.1.start())
311 }
312
313 fn is_match(&self, state: &IntersectionState<A, B>) -> bool {
314 self.0.is_match(&state.0) && self.1.is_match(&state.1)
315 }
316
317 fn can_match(&self, state: &IntersectionState<A, B>) -> bool {
318 self.0.can_match(&state.0) && self.1.can_match(&state.1)
319 }
320
321 fn will_always_match(&self, state: &IntersectionState<A, B>) -> bool {
322 self.0.will_always_match(&state.0) && self.1.will_always_match(&state.1)
323 }
324
325 fn accept(&self, state: &IntersectionState<A, B>, byte: u8) -> IntersectionState<A, B> {
326 IntersectionState(self.0.accept(&state.0, byte), self.1.accept(&state.1, byte))
327 }
328}
329
330#[derive(Clone, Debug)]
332pub struct Complement<A>(A);
333
334pub struct ComplementState<A: Automaton>(A::State);
336
337impl<A: Automaton> Automaton for Complement<A> {
338 type State = ComplementState<A>;
339
340 fn start(&self) -> ComplementState<A> {
341 ComplementState(self.0.start())
342 }
343
344 fn is_match(&self, state: &ComplementState<A>) -> bool {
345 !self.0.is_match(&state.0)
346 }
347
348 fn can_match(&self, state: &ComplementState<A>) -> bool {
349 !self.0.will_always_match(&state.0)
350 }
351
352 fn will_always_match(&self, state: &ComplementState<A>) -> bool {
353 !self.0.can_match(&state.0)
354 }
355
356 fn accept(&self, state: &ComplementState<A>, byte: u8) -> ComplementState<A> {
357 ComplementState(self.0.accept(&state.0, byte))
358 }
359}