xref: /third_party/rust/crates/regex/src/pattern.rs (revision c67d6573)
1use std::str::pattern::{Pattern, SearchStep, Searcher};
2
3use crate::re_unicode::{Matches, Regex};
4
5#[derive(Debug)]
6pub 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
13impl<'r, 't> Pattern<'t> for &'r Regex {
14    type Searcher = RegexSearcher<'r, 't>;
15
16    fn into_searcher(self, haystack: &'t str) -> RegexSearcher<'r, 't> {
17        RegexSearcher {
18            haystack,
19            it: self.find_iter(haystack),
20            last_step_end: 0,
21            next_match: None,
22        }
23    }
24}
25
26unsafe impl<'r, 't> Searcher<'t> for RegexSearcher<'r, 't> {
27    #[inline]
28    fn haystack(&self) -> &'t str {
29        self.haystack
30    }
31
32    #[inline]
33    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