blob: b4ffd8e165fdfc3ad67ba496991b795efa1c2e94 [file] [log] [blame]
Chih-Hung Hsiehe42c5052020-04-16 10:44:21 -07001use std::str::pattern::{Pattern, SearchStep, Searcher};
2
Joel Galenson38748082021-05-19 16:51:51 -07003use crate::re_unicode::{Matches, Regex};
Chih-Hung Hsiehe42c5052020-04-16 10:44:21 -07004
Joel Galenson38748082021-05-19 16:51:51 -07005#[derive(Debug)]
Chih-Hung Hsiehe42c5052020-04-16 10:44:21 -07006pub 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: 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}