@@ -214,7 +214,7 @@ pub struct Fsm<'a> {
214
214
#[ derive( Clone , Debug ) ]
215
215
pub enum Result < T > {
216
216
Match ( T ) ,
217
- NoMatch ,
217
+ NoMatch ( usize ) ,
218
218
Quit ,
219
219
}
220
220
@@ -223,7 +223,28 @@ impl<T> Result<T> {
223
223
pub fn is_match ( & self ) -> bool {
224
224
match * self {
225
225
Result :: Match ( _) => true ,
226
- Result :: NoMatch | Result :: Quit => false ,
226
+ Result :: NoMatch ( _) | Result :: Quit => false ,
227
+ }
228
+ }
229
+
230
+ /// Maps the given function onto T and returns the result.
231
+ ///
232
+ /// If this isn't a match, then this is a no-op.
233
+ pub fn map < U , F : FnMut ( T ) -> U > ( self , mut f : F ) -> Result < U > {
234
+ match self {
235
+ Result :: Match ( t) => Result :: Match ( f ( t) ) ,
236
+ Result :: NoMatch ( x) => Result :: NoMatch ( x) ,
237
+ Result :: Quit => Result :: Quit ,
238
+ }
239
+ }
240
+
241
+ /// Sets the non-match position.
242
+ ///
243
+ /// If this isn't a non-match, then this is a no-op.
244
+ fn set_non_match ( self , at : usize ) -> Result < T > {
245
+ match self {
246
+ Result :: NoMatch ( _) => Result :: NoMatch ( at) ,
247
+ r => r,
227
248
}
228
249
}
229
250
}
@@ -465,7 +486,7 @@ impl<'a> Fsm<'a> {
465
486
state_flags,
466
487
) {
467
488
None => return Result :: Quit ,
468
- Some ( STATE_DEAD ) => return Result :: NoMatch ,
489
+ Some ( STATE_DEAD ) => return Result :: NoMatch ( at ) ,
469
490
Some ( si) => si,
470
491
} ;
471
492
debug_assert ! ( dfa. start != STATE_UNKNOWN ) ;
@@ -498,7 +519,7 @@ impl<'a> Fsm<'a> {
498
519
state_flags,
499
520
) {
500
521
None => return Result :: Quit ,
501
- Some ( STATE_DEAD ) => return Result :: NoMatch ,
522
+ Some ( STATE_DEAD ) => return Result :: NoMatch ( at ) ,
502
523
Some ( si) => si,
503
524
} ;
504
525
debug_assert ! ( dfa. start != STATE_UNKNOWN ) ;
@@ -532,7 +553,7 @@ impl<'a> Fsm<'a> {
532
553
state_flags,
533
554
) {
534
555
None => return Result :: Quit ,
535
- Some ( STATE_DEAD ) => return Result :: NoMatch ,
556
+ Some ( STATE_DEAD ) => return Result :: NoMatch ( at ) ,
536
557
Some ( si) => si,
537
558
} ;
538
559
debug_assert ! ( dfa. start != STATE_UNKNOWN ) ;
@@ -601,7 +622,7 @@ impl<'a> Fsm<'a> {
601
622
// reported as an index to the most recent byte that resulted in a
602
623
// transition to a match state and is always stored in capture slot `1`
603
624
// when searching forwards. Its maximum value is `text.len()`.
604
- let mut result = Result :: NoMatch ;
625
+ let mut result = Result :: NoMatch ( self . at ) ;
605
626
let ( mut prev_si, mut next_si) = ( self . start , self . start ) ;
606
627
let mut at = self . at ;
607
628
while at < text. len ( ) {
@@ -690,7 +711,7 @@ impl<'a> Fsm<'a> {
690
711
next_si &= !STATE_START ;
691
712
prev_si = next_si;
692
713
at = match self . prefix_at ( text, at) {
693
- None => return Result :: NoMatch ,
714
+ None => return Result :: NoMatch ( text . len ( ) ) ,
694
715
Some ( i) => i,
695
716
} ;
696
717
} else if next_si >= STATE_UNKNOWN {
@@ -711,7 +732,7 @@ impl<'a> Fsm<'a> {
711
732
self . at = at;
712
733
next_si = match self . next_state ( qcur, qnext, prev_si, byte) {
713
734
None => return Result :: Quit ,
714
- Some ( STATE_DEAD ) => return result,
735
+ Some ( STATE_DEAD ) => return result. set_non_match ( at ) ,
715
736
Some ( si) => si,
716
737
} ;
717
738
debug_assert ! ( next_si != STATE_UNKNOWN ) ;
@@ -735,7 +756,7 @@ impl<'a> Fsm<'a> {
735
756
prev_si &= STATE_MAX ;
736
757
prev_si = match self . next_state ( qcur, qnext, prev_si, Byte :: eof ( ) ) {
737
758
None => return Result :: Quit ,
738
- Some ( STATE_DEAD ) => return result,
759
+ Some ( STATE_DEAD ) => return result. set_non_match ( text . len ( ) ) ,
739
760
Some ( si) => si & !STATE_START ,
740
761
} ;
741
762
debug_assert ! ( prev_si != STATE_UNKNOWN ) ;
@@ -762,7 +783,7 @@ impl<'a> Fsm<'a> {
762
783
// N.B. The code duplication here is regrettable. Efforts to improve
763
784
// it without sacrificing performance are welcome. ---AG
764
785
debug_assert ! ( self . prog. is_reverse) ;
765
- let mut result = Result :: NoMatch ;
786
+ let mut result = Result :: NoMatch ( self . at ) ;
766
787
let ( mut prev_si, mut next_si) = ( self . start , self . start ) ;
767
788
let mut at = self . at ;
768
789
while at > 0 {
@@ -816,7 +837,7 @@ impl<'a> Fsm<'a> {
816
837
self . at = at;
817
838
next_si = match self . next_state ( qcur, qnext, prev_si, byte) {
818
839
None => return Result :: Quit ,
819
- Some ( STATE_DEAD ) => return result,
840
+ Some ( STATE_DEAD ) => return result. set_non_match ( at ) ,
820
841
Some ( si) => si,
821
842
} ;
822
843
debug_assert ! ( next_si != STATE_UNKNOWN ) ;
@@ -837,7 +858,7 @@ impl<'a> Fsm<'a> {
837
858
// Run the DFA once more on the special EOF senitnel value.
838
859
prev_si = match self . next_state ( qcur, qnext, prev_si, Byte :: eof ( ) ) {
839
860
None => return Result :: Quit ,
840
- Some ( STATE_DEAD ) => return result,
861
+ Some ( STATE_DEAD ) => return result. set_non_match ( 0 ) ,
841
862
Some ( si) => si,
842
863
} ;
843
864
debug_assert ! ( prev_si != STATE_UNKNOWN ) ;
0 commit comments