1use core::str::pattern::{Pattern, SearchStep, Searcher, Utf8Pattern};
2
3use crate::{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> Pattern for &'r Regex {
14 type Searcher<'t> = RegexSearcher<'r, 't>;
15
16 fn into_searcher<'t>(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 fn as_utf8_pattern<'p>(&'p self) -> Option<Utf8Pattern<'p>> {
26 None
27 }
28}
29
30unsafe impl<'r, 't> Searcher<'t> for RegexSearcher<'r, 't> {
31 #[inline]
32 fn haystack(&self) -> &'t str {
33 self.haystack
34 }
35
36 #[inline]
37 fn next(&mut self) -> SearchStep {
38 if let Some((s, e)) = self.next_match {
39 self.next_match = None;
40 self.last_step_end = e;
41 return SearchStep::Match(s, e);
42 }
43 match self.it.next() {
44 None => {
45 if self.last_step_end < self.haystack().len() {
46 let last = self.last_step_end;
47 self.last_step_end = self.haystack().len();
48 SearchStep::Reject(last, self.haystack().len())
49 } else {
50 SearchStep::Done
51 }
52 }
53 Some(m) => {
54 let (s, e) = (m.start(), m.end());
55 if s == self.last_step_end {
56 self.last_step_end = e;
57 SearchStep::Match(s, e)
58 } else {
59 self.next_match = Some((s, e));
60 let last = self.last_step_end;
61 self.last_step_end = s;
62 SearchStep::Reject(last, s)
63 }
64 }
65 }
66 }
67}