1#[cfg(feature = "levenshtein")]
2pub use self::levenshtein::{Levenshtein, LevenshteinError};
3
4#[cfg(feature = "levenshtein")]
5mod levenshtein;
6
7pub trait Automaton {
29 type State;
31
32 fn start(&self) -> Self::State;
37
38 fn is_match(&self, state: &Self::State) -> bool;
40
41 fn can_match(&self, _state: &Self::State) -> bool {
51 true
52 }
53
54 fn will_always_match(&self, _state: &Self::State) -> bool {
65 false
66 }
67
68 fn accept(&self, state: &Self::State, byte: u8) -> Self::State;
70
71 fn accept_eof(&self, _: &Self::State) -> Option<Self::State> {
73 None
74 }
75
76 fn starts_with(self) -> StartsWith<Self>
79 where
80 Self: Sized,
81 {
82 StartsWith(self)
83 }
84
85 fn union<Rhs: Automaton>(self, rhs: Rhs) -> Union<Self, Rhs>
88 where
89 Self: Sized,
90 {
91 Union(self, rhs)
92 }
93
94 fn intersection<Rhs: Automaton>(self, rhs: Rhs) -> Intersection<Self, Rhs>
97 where
98 Self: Sized,
99 {
100 Intersection(self, rhs)
101 }
102
103 fn complement(self) -> Complement<Self>
106 where
107 Self: Sized,
108 {
109 Complement(self)
110 }
111}
112
113impl<'a, T: Automaton> Automaton for &'a T {
114 type State = T::State;
115
116 fn start(&self) -> T::State {
117 (*self).start()
118 }
119
120 fn is_match(&self, state: &T::State) -> bool {
121 (*self).is_match(state)
122 }
123
124 fn can_match(&self, state: &T::State) -> bool {
125 (*self).can_match(state)
126 }
127
128 fn will_always_match(&self, state: &T::State) -> bool {
129 (*self).will_always_match(state)
130 }
131
132 fn accept(&self, state: &T::State, byte: u8) -> T::State {
133 (*self).accept(state, byte)
134 }
135
136 fn accept_eof(&self, state: &Self::State) -> Option<Self::State> {
137 (*self).accept_eof(state)
138 }
139}
140
141#[derive(Clone, Debug)]
169pub struct Str<'a> {
170 string: &'a [u8],
171}
172
173impl<'a> Str<'a> {
174 #[inline]
176 pub fn new(string: &'a str) -> Str<'a> {
177 Str { string: string.as_bytes() }
178 }
179}
180
181impl<'a> Automaton for Str<'a> {
182 type State = Option<usize>;
183
184 #[inline]
185 fn start(&self) -> Option<usize> {
186 Some(0)
187 }
188
189 #[inline]
190 fn is_match(&self, pos: &Option<usize>) -> bool {
191 *pos == Some(self.string.len())
192 }
193
194 #[inline]
195 fn can_match(&self, pos: &Option<usize>) -> bool {
196 pos.is_some()
197 }
198
199 #[inline]
200 fn accept(&self, pos: &Option<usize>, byte: u8) -> Option<usize> {
201 if let Some(pos) = *pos {
203 if self.string.get(pos).cloned() == Some(byte) {
205 return Some(pos + 1);
207 }
208 }
209 None
211 }
212}
213
214#[derive(Clone, Debug)]
241pub struct Subsequence<'a> {
242 subseq: &'a [u8],
243}
244
245impl<'a> Subsequence<'a> {
246 #[inline]
249 pub fn new(subsequence: &'a str) -> Subsequence<'a> {
250 Subsequence { subseq: subsequence.as_bytes() }
251 }
252}
253
254impl<'a> Automaton for Subsequence<'a> {
255 type State = usize;
256
257 #[inline]
258 fn start(&self) -> usize {
259 0
260 }
261
262 #[inline]
263 fn is_match(&self, &state: &usize) -> bool {
264 state == self.subseq.len()
265 }
266
267 #[inline]
268 fn can_match(&self, _: &usize) -> bool {
269 true
270 }
271
272 #[inline]
273 fn will_always_match(&self, &state: &usize) -> bool {
274 state == self.subseq.len()
275 }
276
277 #[inline]
278 fn accept(&self, &state: &usize, byte: u8) -> usize {
279 if state == self.subseq.len() {
280 return state;
281 }
282 state + (byte == self.subseq[state]) as usize
283 }
284}
285
286#[derive(Clone, Debug)]
291pub struct AlwaysMatch;
292
293impl Automaton for AlwaysMatch {
294 type State = ();
295
296 #[inline]
297 fn start(&self) -> () {
298 ()
299 }
300 #[inline]
301 fn is_match(&self, _: &()) -> bool {
302 true
303 }
304 #[inline]
305 fn can_match(&self, _: &()) -> bool {
306 true
307 }
308 #[inline]
309 fn will_always_match(&self, _: &()) -> bool {
310 true
311 }
312 #[inline]
313 fn accept(&self, _: &(), _: u8) -> () {
314 ()
315 }
316}
317
318#[derive(Clone, Debug)]
321pub struct StartsWith<A>(A);
322
323pub struct StartsWithState<A: Automaton>(StartsWithStateKind<A>);
325
326enum StartsWithStateKind<A: Automaton> {
327 Done,
328 Running(A::State),
329}
330
331impl<A: Automaton> Automaton for StartsWith<A> {
332 type State = StartsWithState<A>;
333
334 fn start(&self) -> StartsWithState<A> {
335 StartsWithState({
336 let inner = self.0.start();
337 if self.0.is_match(&inner) {
338 StartsWithStateKind::Done
339 } else {
340 StartsWithStateKind::Running(inner)
341 }
342 })
343 }
344
345 fn is_match(&self, state: &StartsWithState<A>) -> bool {
346 match state.0 {
347 StartsWithStateKind::Done => true,
348 StartsWithStateKind::Running(_) => false,
349 }
350 }
351
352 fn can_match(&self, state: &StartsWithState<A>) -> bool {
353 match state.0 {
354 StartsWithStateKind::Done => true,
355 StartsWithStateKind::Running(ref inner) => self.0.can_match(inner),
356 }
357 }
358
359 fn will_always_match(&self, state: &StartsWithState<A>) -> bool {
360 match state.0 {
361 StartsWithStateKind::Done => true,
362 StartsWithStateKind::Running(_) => false,
363 }
364 }
365
366 fn accept(
367 &self,
368 state: &StartsWithState<A>,
369 byte: u8,
370 ) -> StartsWithState<A> {
371 StartsWithState(match state.0 {
372 StartsWithStateKind::Done => StartsWithStateKind::Done,
373 StartsWithStateKind::Running(ref inner) => {
374 let next_inner = self.0.accept(inner, byte);
375 if self.0.is_match(&next_inner) {
376 StartsWithStateKind::Done
377 } else {
378 StartsWithStateKind::Running(next_inner)
379 }
380 }
381 })
382 }
383}
384
385#[derive(Clone, Debug)]
387pub struct Union<A, B>(A, B);
388
389pub struct UnionState<A: Automaton, B: Automaton>(A::State, B::State);
391
392impl<A: Automaton, B: Automaton> Automaton for Union<A, B> {
393 type State = UnionState<A, B>;
394
395 fn start(&self) -> UnionState<A, B> {
396 UnionState(self.0.start(), self.1.start())
397 }
398
399 fn is_match(&self, state: &UnionState<A, B>) -> bool {
400 self.0.is_match(&state.0) || self.1.is_match(&state.1)
401 }
402
403 fn can_match(&self, state: &UnionState<A, B>) -> bool {
404 self.0.can_match(&state.0) || self.1.can_match(&state.1)
405 }
406
407 fn will_always_match(&self, state: &UnionState<A, B>) -> bool {
408 self.0.will_always_match(&state.0)
409 || self.1.will_always_match(&state.1)
410 }
411
412 fn accept(&self, state: &UnionState<A, B>, byte: u8) -> UnionState<A, B> {
413 UnionState(
414 self.0.accept(&state.0, byte),
415 self.1.accept(&state.1, byte),
416 )
417 }
418}
419
420#[derive(Clone, Debug)]
422pub struct Intersection<A, B>(A, B);
423
424pub struct IntersectionState<A: Automaton, B: Automaton>(A::State, B::State);
426
427impl<A: Automaton, B: Automaton> Automaton for Intersection<A, B> {
428 type State = IntersectionState<A, B>;
429
430 fn start(&self) -> IntersectionState<A, B> {
431 IntersectionState(self.0.start(), self.1.start())
432 }
433
434 fn is_match(&self, state: &IntersectionState<A, B>) -> bool {
435 self.0.is_match(&state.0) && self.1.is_match(&state.1)
436 }
437
438 fn can_match(&self, state: &IntersectionState<A, B>) -> bool {
439 self.0.can_match(&state.0) && self.1.can_match(&state.1)
440 }
441
442 fn will_always_match(&self, state: &IntersectionState<A, B>) -> bool {
443 self.0.will_always_match(&state.0)
444 && self.1.will_always_match(&state.1)
445 }
446
447 fn accept(
448 &self,
449 state: &IntersectionState<A, B>,
450 byte: u8,
451 ) -> IntersectionState<A, B> {
452 IntersectionState(
453 self.0.accept(&state.0, byte),
454 self.1.accept(&state.1, byte),
455 )
456 }
457}
458
459#[derive(Clone, Debug)]
461pub struct Complement<A>(A);
462
463pub struct ComplementState<A: Automaton>(A::State);
465
466impl<A: Automaton> Automaton for Complement<A> {
467 type State = ComplementState<A>;
468
469 fn start(&self) -> ComplementState<A> {
470 ComplementState(self.0.start())
471 }
472
473 fn is_match(&self, state: &ComplementState<A>) -> bool {
474 !self.0.is_match(&state.0)
475 }
476
477 fn can_match(&self, state: &ComplementState<A>) -> bool {
478 !self.0.will_always_match(&state.0)
479 }
480
481 fn will_always_match(&self, state: &ComplementState<A>) -> bool {
482 !self.0.can_match(&state.0)
483 }
484
485 fn accept(
486 &self,
487 state: &ComplementState<A>,
488 byte: u8,
489 ) -> ComplementState<A> {
490 ComplementState(self.0.accept(&state.0, byte))
491 }
492}