1 use std::str::pattern::{Pattern, SearchStep, Searcher};
2 
3 use re_unicode::{Matches, Regex};
4 
5 pub struct RegexSearcher<'r, 't> {
6     haystack: &'t str,
7     it: Matches<'r, 't>,
8     last_step_end: usize,
9     next_match: Option<(usize, usize)>,
10 }
11 
12 impl<'r, 't> Pattern<'t> for &'r Regex {
13     type Searcher = RegexSearcher<'r, 't>;
14 
into_searcher(self, haystack: &'t str) -> RegexSearcher<'r, 't>15     fn into_searcher(self, haystack: &'t str) -> RegexSearcher<'r, 't> {
16         RegexSearcher {
17             haystack: haystack,
18             it: self.find_iter(haystack),
19             last_step_end: 0,
20             next_match: None,
21         }
22     }
23 }
24 
25 unsafe impl<'r, 't> Searcher<'t> for RegexSearcher<'r, 't> {
26     #[inline]
haystack(&self) -> &'t str27     fn haystack(&self) -> &'t str {
28         self.haystack
29     }
30 
31     #[inline]
next(&mut self) -> SearchStep32     fn next(&mut self) -> SearchStep {
33         if let Some((s, e)) = self.next_match {
34             self.next_match = None;
35             self.last_step_end = e;
36             return SearchStep::Match(s, e);
37         }
38         match self.it.next() {
39             None => {
40                 if self.last_step_end < self.haystack().len() {
41                     let last = self.last_step_end;
42                     self.last_step_end = self.haystack().len();
43                     SearchStep::Reject(last, self.haystack().len())
44                 } else {
45                     SearchStep::Done
46                 }
47             }
48             Some(m) => {
49                 let (s, e) = (m.start(), m.end());
50                 if s == self.last_step_end {
51                     self.last_step_end = e;
52                     SearchStep::Match(s, e)
53                 } else {
54                     self.next_match = Some((s, e));
55                     let last = self.last_step_end;
56                     self.last_step_end = s;
57                     SearchStep::Reject(last, s)
58                 }
59             }
60         }
61     }
62 }
63