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