1 use std::str::pattern::{Pattern, SearchStep, Searcher}; 2 3 use re_unicode::{Matches, Regex}; 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 into_searcher(self, haystack: &'t str) -> RegexSearcher<'r, 't>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] haystack(&self) -> &'t str27 fn haystack(&self) -> &'t str { 28 self.haystack 29 } 30 31 #[inline] next(&mut self) -> SearchStep32 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 } 63