@@ -128,6 +128,11 @@ pub unsafe trait Searcher<'a> {
128
128
fn next ( & mut self ) -> SearchStep ;
129
129
130
130
/// 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.
131
136
#[ inline]
132
137
fn next_match ( & mut self ) -> Option < ( usize , usize ) > {
133
138
loop {
@@ -139,7 +144,10 @@ pub unsafe trait Searcher<'a> {
139
144
}
140
145
}
141
146
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.
143
151
#[ inline]
144
152
fn next_reject ( & mut self ) -> Option < ( usize , usize ) > {
145
153
loop {
@@ -244,8 +252,9 @@ pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {}
244
252
#[ derive( Clone , Debug ) ]
245
253
pub struct CharSearcher < ' a > {
246
254
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`
248
256
finger : usize ,
257
+ finger_back : usize ,
249
258
needle : char ,
250
259
// For ascii chars
251
260
// invariant: must be an ASCII byte (no high bit)
@@ -266,7 +275,7 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
266
275
if let Some ( ch) = iter. next ( ) {
267
276
// add byte offset of current character
268
277
// without recalculating
269
- self . finger += iter. iter . len ( ) - old_len ;
278
+ self . finger += old_len - iter. iter . len ( ) ;
270
279
if ch == self . needle {
271
280
SearchStep :: Match ( old_finger, self . finger )
272
281
} else {
@@ -286,7 +295,7 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
286
295
// index is the index of a valid ASCII byte,
287
296
// so we can add one to it
288
297
self . finger += index + 1 ;
289
- Some ( ( index , self . finger ) )
298
+ Some ( ( self . finger - 1 , self . finger ) )
290
299
} else {
291
300
None
292
301
}
@@ -307,11 +316,45 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
307
316
unsafe impl < ' a > ReverseSearcher < ' a > for CharSearcher < ' a > {
308
317
#[ inline]
309
318
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
+ }
311
335
}
312
336
#[ inline]
313
337
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
+ }
315
358
}
316
359
317
360
// let next_reject_back use the default implementation from the Searcher trait
@@ -335,6 +378,7 @@ impl<'a> Pattern<'a> for char {
335
378
CharSearcher {
336
379
haystack,
337
380
finger : 0 ,
381
+ finger_back : haystack. len ( ) ,
338
382
needle : self ,
339
383
single_byte,
340
384
}
0 commit comments