@@ -47,6 +47,22 @@ pub trait Pattern<'a>: Sized {
47
47
matches ! ( self . into_searcher( haystack) . next( ) , SearchStep :: Match ( 0 , _) )
48
48
}
49
49
50
+ /// Removes the pattern from the front of haystack, if it matches.
51
+ #[ inline]
52
+ fn strip_prefix_of ( self , haystack : & ' a str ) -> Option < & ' a str > {
53
+ if let SearchStep :: Match ( start, len) = self . into_searcher ( haystack) . next ( ) {
54
+ debug_assert_eq ! (
55
+ start, 0 ,
56
+ "The first search step from Searcher \
57
+ must include the first character"
58
+ ) ;
59
+ // SAFETY: `Searcher` is known to return valid indices.
60
+ unsafe { Some ( haystack. get_unchecked ( len..) ) }
61
+ } else {
62
+ None
63
+ }
64
+ }
65
+
50
66
/// Checks whether the pattern matches at the back of the haystack
51
67
#[ inline]
52
68
fn is_suffix_of ( self , haystack : & ' a str ) -> bool
@@ -55,6 +71,26 @@ pub trait Pattern<'a>: Sized {
55
71
{
56
72
matches ! ( self . into_searcher( haystack) . next_back( ) , SearchStep :: Match ( _, j) if haystack. len( ) == j)
57
73
}
74
+
75
+ /// Removes the pattern from the back of haystack, if it matches.
76
+ #[ inline]
77
+ fn strip_suffix_of ( self , haystack : & ' a str ) -> Option < & ' a str >
78
+ where
79
+ Self :: Searcher : ReverseSearcher < ' a > ,
80
+ {
81
+ if let SearchStep :: Match ( start, end) = self . into_searcher ( haystack) . next_back ( ) {
82
+ debug_assert_eq ! (
83
+ end,
84
+ haystack. len( ) ,
85
+ "The first search step from ReverseSearcher \
86
+ must include the last character"
87
+ ) ;
88
+ // SAFETY: `Searcher` is known to return valid indices.
89
+ unsafe { Some ( haystack. get_unchecked ( ..start) ) }
90
+ } else {
91
+ None
92
+ }
93
+ }
58
94
}
59
95
60
96
// Searcher
@@ -448,13 +484,26 @@ impl<'a> Pattern<'a> for char {
448
484
self . encode_utf8 ( & mut [ 0u8 ; 4 ] ) . is_prefix_of ( haystack)
449
485
}
450
486
487
+ #[ inline]
488
+ fn strip_prefix_of ( self , haystack : & ' a str ) -> Option < & ' a str > {
489
+ self . encode_utf8 ( & mut [ 0u8 ; 4 ] ) . strip_prefix_of ( haystack)
490
+ }
491
+
451
492
#[ inline]
452
493
fn is_suffix_of ( self , haystack : & ' a str ) -> bool
453
494
where
454
495
Self :: Searcher : ReverseSearcher < ' a > ,
455
496
{
456
497
self . encode_utf8 ( & mut [ 0u8 ; 4 ] ) . is_suffix_of ( haystack)
457
498
}
499
+
500
+ #[ inline]
501
+ fn strip_suffix_of ( self , haystack : & ' a str ) -> Option < & ' a str >
502
+ where
503
+ Self :: Searcher : ReverseSearcher < ' a > ,
504
+ {
505
+ self . encode_utf8 ( & mut [ 0u8 ; 4 ] ) . strip_suffix_of ( haystack)
506
+ }
458
507
}
459
508
460
509
/////////////////////////////////////////////////////////////////////////////
@@ -569,13 +618,26 @@ macro_rules! pattern_methods {
569
618
( $pmap) ( self ) . is_prefix_of( haystack)
570
619
}
571
620
621
+ #[ inline]
622
+ fn strip_prefix_of( self , haystack: & ' a str ) -> Option <& ' a str > {
623
+ ( $pmap) ( self ) . strip_prefix_of( haystack)
624
+ }
625
+
572
626
#[ inline]
573
627
fn is_suffix_of( self , haystack: & ' a str ) -> bool
574
628
where
575
629
$t: ReverseSearcher <' a>,
576
630
{
577
631
( $pmap) ( self ) . is_suffix_of( haystack)
578
632
}
633
+
634
+ #[ inline]
635
+ fn strip_suffix_of( self , haystack: & ' a str ) -> Option <& ' a str >
636
+ where
637
+ $t: ReverseSearcher <' a>,
638
+ {
639
+ ( $pmap) ( self ) . strip_suffix_of( haystack)
640
+ }
579
641
} ;
580
642
}
581
643
@@ -715,11 +777,34 @@ impl<'a, 'b> Pattern<'a> for &'b str {
715
777
haystack. as_bytes ( ) . starts_with ( self . as_bytes ( ) )
716
778
}
717
779
780
+ /// Removes the pattern from the front of haystack, if it matches.
781
+ #[ inline]
782
+ fn strip_prefix_of ( self , haystack : & ' a str ) -> Option < & ' a str > {
783
+ if self . is_prefix_of ( haystack) {
784
+ // SAFETY: prefix was just verified to exist.
785
+ unsafe { Some ( haystack. get_unchecked ( self . as_bytes ( ) . len ( ) ..) ) }
786
+ } else {
787
+ None
788
+ }
789
+ }
790
+
718
791
/// Checks whether the pattern matches at the back of the haystack
719
792
#[ inline]
720
793
fn is_suffix_of ( self , haystack : & ' a str ) -> bool {
721
794
haystack. as_bytes ( ) . ends_with ( self . as_bytes ( ) )
722
795
}
796
+
797
+ /// Removes the pattern from the back of haystack, if it matches.
798
+ #[ inline]
799
+ fn strip_suffix_of ( self , haystack : & ' a str ) -> Option < & ' a str > {
800
+ if self . is_suffix_of ( haystack) {
801
+ let i = haystack. len ( ) - self . as_bytes ( ) . len ( ) ;
802
+ // SAFETY: suffix was just verified to exist.
803
+ unsafe { Some ( haystack. get_unchecked ( ..i) ) }
804
+ } else {
805
+ None
806
+ }
807
+ }
723
808
}
724
809
725
810
/////////////////////////////////////////////////////////////////////////////
0 commit comments