@@ -128,6 +128,11 @@ pub unsafe trait Searcher<'a> {
128128 fn next ( & mut self ) -> SearchStep ;
129129
130130 /// Find the next `Match` result. See `next()`
131+ ///
132+ /// Unlike next(), there is no guarantee that the returned ranges
133+ /// of this and next_reject will overlap. This will return (start_match, end_match),
134+ /// where start_match is the index of where the match begins, and end_match is
135+ /// the index after the end of the match.
131136 #[ inline]
132137 fn next_match ( & mut self ) -> Option < ( usize , usize ) > {
133138 loop {
@@ -139,7 +144,10 @@ pub unsafe trait Searcher<'a> {
139144 }
140145 }
141146
142- /// Find the next `Reject` result. See `next()`
147+ /// Find the next `Reject` result. See `next()` and `next_match()`
148+ ///
149+ /// Unlike next(), there is no guarantee that the returned ranges
150+ /// of this and next_match will overlap.
143151 #[ inline]
144152 fn next_reject ( & mut self ) -> Option < ( usize , usize ) > {
145153 loop {
@@ -244,8 +252,9 @@ pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {}
244252#[ derive( Clone , Debug ) ]
245253pub struct CharSearcher < ' a > {
246254 haystack : & ' a str ,
247- // invariant: `finger` must be a valid utf8 byte index of `haystack`
255+ // invariant: `finger`/`finger_back` must be a valid utf8 byte index of `haystack`
248256 finger : usize ,
257+ finger_back : usize ,
249258 needle : char ,
250259 // For ascii chars
251260 // invariant: must be an ASCII byte (no high bit)
@@ -266,7 +275,7 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
266275 if let Some ( ch) = iter. next ( ) {
267276 // add byte offset of current character
268277 // without recalculating
269- self . finger += iter. iter . len ( ) - old_len ;
278+ self . finger += old_len - iter. iter . len ( ) ;
270279 if ch == self . needle {
271280 SearchStep :: Match ( old_finger, self . finger )
272281 } else {
@@ -286,7 +295,7 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
286295 // index is the index of a valid ASCII byte,
287296 // so we can add one to it
288297 self . finger += index + 1 ;
289- Some ( ( index , self . finger ) )
298+ Some ( ( self . finger - 1 , self . finger ) )
290299 } else {
291300 None
292301 }
@@ -307,11 +316,45 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
307316unsafe impl < ' a > ReverseSearcher < ' a > for CharSearcher < ' a > {
308317 #[ inline]
309318 fn next_back ( & mut self ) -> SearchStep {
310- unimplemented ! ( ) ;
319+ let old_finger = self . finger_back ;
320+ let slice = unsafe { self . haystack . slice_unchecked ( 0 , old_finger) } ;
321+ let mut iter = slice. chars ( ) ;
322+ let old_len = iter. iter . len ( ) ;
323+ if let Some ( ch) = iter. next_back ( ) {
324+ // subtract byte offset of current character
325+ // without recalculating
326+ self . finger_back -= old_len - iter. iter . len ( ) ;
327+ if ch == self . needle {
328+ SearchStep :: Match ( self . finger_back , old_finger)
329+ } else {
330+ SearchStep :: Reject ( self . finger_back , old_finger)
331+ }
332+ } else {
333+ SearchStep :: Done
334+ }
311335 }
312336 #[ inline]
313337 fn next_match_back ( & mut self ) -> Option < ( usize , usize ) > {
314- unimplemented ! ( ) ;
338+ if let Some ( byte) = self . single_byte {
339+ let old_finger = self . finger_back ;
340+ let slice = unsafe { self . haystack . slice_unchecked ( 0 , old_finger) } ;
341+ let bytes = slice. as_bytes ( ) ;
342+ if let Some ( index) = memchr:: memrchr ( byte, bytes) {
343+ // index is the index of a valid ASCII byte
344+ self . finger_back = index;
345+ Some ( ( self . finger_back , self . finger_back + 1 ) )
346+ } else {
347+ None
348+ }
349+ } else {
350+ loop {
351+ match self . next_back ( ) {
352+ SearchStep :: Match ( a, b) => break Some ( ( a, b) ) ,
353+ SearchStep :: Done => break None ,
354+ _ => continue ,
355+ }
356+ }
357+ }
315358 }
316359
317360 // let next_reject_back use the default implementation from the Searcher trait
@@ -335,6 +378,7 @@ impl<'a> Pattern<'a> for char {
335378 CharSearcher {
336379 haystack,
337380 finger : 0 ,
381+ finger_back : haystack. len ( ) ,
338382 needle : self ,
339383 single_byte,
340384 }
0 commit comments