]>
Commit | Line | Data |
---|---|---|
f9f354fc | 1 | use std::str::pattern::{Pattern, SearchStep, Searcher}; |
94b46f34 | 2 | |
f9f354fc | 3 | use re_unicode::{Matches, Regex}; |
94b46f34 XL |
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 | ||
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] | |
27 | fn haystack(&self) -> &'t str { | |
28 | self.haystack | |
29 | } | |
30 | ||
31 | #[inline] | |
32 | 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 | } |