1use std::str::pattern::{Pattern, SearchStep, Searcher}; 2 3use crate::re_unicode::{Matches, Regex}; 4 5#[derive(Debug)] 6pub 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, 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} 64