Chih-Hung Hsieh | e42c505 | 2020-04-16 10:44:21 -0700 | [diff] [blame] | 1 | use std::str::pattern::{Pattern, SearchStep, Searcher}; |
| 2 | |
Joel Galenson | 3874808 | 2021-05-19 16:51:51 -0700 | [diff] [blame] | 3 | use crate::re_unicode::{Matches, Regex}; |
Chih-Hung Hsieh | e42c505 | 2020-04-16 10:44:21 -0700 | [diff] [blame] | 4 | |
Joel Galenson | 3874808 | 2021-05-19 16:51:51 -0700 | [diff] [blame] | 5 | #[derive(Debug)] |
Chih-Hung Hsieh | e42c505 | 2020-04-16 10:44:21 -0700 | [diff] [blame] | 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 | |
| 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] |
| 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 | } |