1 use std::str::pattern::{Pattern, SearchStep, Searcher}; 2 3 use crate::re_unicode::{Matches, Regex}; 4 5 #[derive(Debug)] 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 into_searcher(self, haystack: &'t str) -> RegexSearcher<'r, 't>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 26 unsafe impl<'r, 't> Searcher<'t> for RegexSearcher<'r, 't> { 27 #[inline] haystack(&self) -> &'t str28 fn haystack(&self) -> &'t str { 29 self.haystack 30 } 31 32 #[inline] next(&mut self) -> SearchStep33 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