@@ -47,6 +47,22 @@ pub trait Pattern<'a>: Sized {
4747 matches ! ( self . into_searcher( haystack) . next( ) , SearchStep :: Match ( 0 , _) )
4848 }
4949
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+
5066 /// Checks whether the pattern matches at the back of the haystack
5167 #[ inline]
5268 fn is_suffix_of ( self , haystack : & ' a str ) -> bool
@@ -55,6 +71,26 @@ pub trait Pattern<'a>: Sized {
5571 {
5672 matches ! ( self . into_searcher( haystack) . next_back( ) , SearchStep :: Match ( _, j) if haystack. len( ) == j)
5773 }
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+ }
5894}
5995
6096// Searcher
@@ -448,13 +484,26 @@ impl<'a> Pattern<'a> for char {
448484 self . encode_utf8 ( & mut [ 0u8 ; 4 ] ) . is_prefix_of ( haystack)
449485 }
450486
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+
451492 #[ inline]
452493 fn is_suffix_of ( self , haystack : & ' a str ) -> bool
453494 where
454495 Self :: Searcher : ReverseSearcher < ' a > ,
455496 {
456497 self . encode_utf8 ( & mut [ 0u8 ; 4 ] ) . is_suffix_of ( haystack)
457498 }
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+ }
458507}
459508
460509/////////////////////////////////////////////////////////////////////////////
@@ -569,13 +618,26 @@ macro_rules! pattern_methods {
569618 ( $pmap) ( self ) . is_prefix_of( haystack)
570619 }
571620
621+ #[ inline]
622+ fn strip_prefix_of( self , haystack: & ' a str ) -> Option <& ' a str > {
623+ ( $pmap) ( self ) . strip_prefix_of( haystack)
624+ }
625+
572626 #[ inline]
573627 fn is_suffix_of( self , haystack: & ' a str ) -> bool
574628 where
575629 $t: ReverseSearcher <' a>,
576630 {
577631 ( $pmap) ( self ) . is_suffix_of( haystack)
578632 }
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+ }
579641 } ;
580642}
581643
@@ -715,11 +777,34 @@ impl<'a, 'b> Pattern<'a> for &'b str {
715777 haystack. as_bytes ( ) . starts_with ( self . as_bytes ( ) )
716778 }
717779
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+
718791 /// Checks whether the pattern matches at the back of the haystack
719792 #[ inline]
720793 fn is_suffix_of ( self , haystack : & ' a str ) -> bool {
721794 haystack. as_bytes ( ) . ends_with ( self . as_bytes ( ) )
722795 }
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+ }
723808}
724809
725810/////////////////////////////////////////////////////////////////////////////
0 commit comments