@@ -983,7 +983,7 @@ impl str {
983983 #[ cfg_attr( not( test) , rustc_diagnostic_item = "str_split_whitespace" ) ]
984984 #[ inline]
985985 pub fn split_whitespace ( & self ) -> SplitWhitespace < ' _ > {
986- SplitWhitespace { inner : self . split ( char :: is_whitespace ) . filter ( |s| !s . is_empty ( ) ) }
986+ SplitWhitespace { inner : self . split ( IsWhitespace ) . filter ( IsNotEmpty ) }
987987 }
988988
989989 /// Splits a string slice by ASCII whitespace.
@@ -1032,13 +1032,8 @@ impl str {
10321032 #[ stable( feature = "split_ascii_whitespace" , since = "1.34.0" ) ]
10331033 #[ inline]
10341034 pub fn split_ascii_whitespace ( & self ) -> SplitAsciiWhitespace < ' _ > {
1035- let inner = self
1036- . as_bytes ( )
1037- . split ( u8:: is_ascii_whitespace)
1038- . filter ( |s| !s. is_empty ( ) )
1039- // SAFETY: the byte slice came from a string and was only split
1040- // along character boundaries, so the resulting slices are strings.
1041- . map ( |bytes| unsafe { from_utf8_unchecked ( bytes) } ) ;
1035+ let inner =
1036+ self . as_bytes ( ) . split ( IsAsciiWhitespace ) . filter ( BytesIsNotEmpty ) . map ( UnsafeBytesToStr ) ;
10421037 SplitAsciiWhitespace { inner }
10431038 }
10441039
@@ -1090,11 +1085,7 @@ impl str {
10901085 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10911086 #[ inline]
10921087 pub fn lines ( & self ) -> Lines < ' _ > {
1093- Lines ( self . split_inclusive ( '\n' ) . map ( |line| {
1094- let Some ( line) = line. strip_suffix ( '\n' ) else { return line } ;
1095- let Some ( line) = line. strip_suffix ( '\r' ) else { return line } ;
1096- line
1097- } ) )
1088+ Lines ( self . split_inclusive ( '\n' ) . map ( LinesMap ) )
10981089 }
10991090
11001091 /// An iterator over the lines of a string.
@@ -2645,19 +2636,14 @@ impl str {
26452636 #[ stable( feature = "str_escape" , since = "1.34.0" ) ]
26462637 pub fn escape_debug ( & self ) -> EscapeDebug < ' _ > {
26472638 let mut chars = self . chars ( ) ;
2648- let first = chars
2649- . next ( )
2650- . map ( |first| first. escape_debug_ext ( EscapeDebugExtArgs :: ESCAPE_ALL ) )
2651- . into_iter ( )
2652- . flatten ( ) ;
2653- let inner = first. chain ( chars. flat_map ( |c| {
2654- c. escape_debug_ext ( EscapeDebugExtArgs {
2655- escape_grapheme_extended : false ,
2656- escape_single_quote : true ,
2657- escape_double_quote : true ,
2658- } )
2659- } ) ) ;
2660- EscapeDebug { inner }
2639+ EscapeDebug {
2640+ inner : chars
2641+ . next ( )
2642+ . map ( |first| first. escape_debug_ext ( EscapeDebugExtArgs :: ESCAPE_ALL ) )
2643+ . into_iter ( )
2644+ . flatten ( )
2645+ . chain ( chars. flat_map ( CharEscapeDebugContinue ) ) ,
2646+ }
26612647 }
26622648
26632649 /// Return an iterator that escapes each char in `self` with [`char::escape_default`].
@@ -2695,7 +2681,7 @@ impl str {
26952681 without modifying the original"]
26962682 #[ stable( feature = "str_escape" , since = "1.34.0" ) ]
26972683 pub fn escape_default ( & self ) -> EscapeDefault < ' _ > {
2698- EscapeDefault { inner : self . chars ( ) . flat_map ( char :: escape_default ) }
2684+ EscapeDefault { inner : self . chars ( ) . flat_map ( CharEscapeDefault ) }
26992685 }
27002686
27012687 /// Return an iterator that escapes each char in `self` with [`char::escape_unicode`].
@@ -2733,7 +2719,7 @@ impl str {
27332719 without modifying the original"]
27342720 #[ stable( feature = "str_escape" , since = "1.34.0" ) ]
27352721 pub fn escape_unicode ( & self ) -> EscapeUnicode < ' _ > {
2736- EscapeUnicode { inner : self . chars ( ) . flat_map ( char :: escape_unicode ) }
2722+ EscapeUnicode { inner : self . chars ( ) . flat_map ( CharEscapeUnicode ) }
27372723 }
27382724}
27392725
@@ -2764,15 +2750,59 @@ impl Default for &mut str {
27642750 }
27652751}
27662752
2767- type LinesMap = impl ( Fn ( & str ) -> & str ) + Copy ;
2768- type CharEscapeDebugContinue = impl ( FnMut ( char ) -> char:: EscapeDebug ) + Copy ;
2769- type CharEscapeUnicode = impl ( Fn ( char ) -> char:: EscapeUnicode ) + Copy ;
2770- type CharEscapeDefault = impl ( Fn ( char ) -> char:: EscapeDefault ) + Copy ;
2771- type IsWhitespace = impl ( Fn ( char ) -> bool ) + Copy ;
2772- type IsAsciiWhitespace = impl ( Fn ( & u8 ) -> bool ) + Copy ;
2773- type IsNotEmpty = impl ( Fn ( & & str ) -> bool ) + Copy ;
2774- type BytesIsNotEmpty < ' a > = impl ( FnMut ( & & ' a [ u8 ] ) -> bool ) + Copy ;
2775- type UnsafeBytesToStr < ' a > = impl ( FnMut ( & ' a [ u8 ] ) -> & ' a str ) + Copy ;
2753+ impl_fn_for_zst ! {
2754+ /// A nameable, cloneable fn type
2755+ #[ derive( Clone ) ]
2756+ struct LinesMap impl <' a> Fn = |line: & ' a str | -> & ' a str {
2757+ let Some ( line) = line. strip_suffix( '\n' ) else { return line } ;
2758+ let Some ( line) = line. strip_suffix( '\r' ) else { return line } ;
2759+ line
2760+ } ;
2761+
2762+ #[ derive( Clone ) ]
2763+ struct CharEscapeDebugContinue impl Fn = |c: char | -> char :: EscapeDebug {
2764+ c. escape_debug_ext( EscapeDebugExtArgs {
2765+ escape_grapheme_extended: false ,
2766+ escape_single_quote: true ,
2767+ escape_double_quote: true
2768+ } )
2769+ } ;
2770+
2771+ #[ derive( Clone ) ]
2772+ struct CharEscapeUnicode impl Fn = |c: char | -> char :: EscapeUnicode {
2773+ c. escape_unicode( )
2774+ } ;
2775+ #[ derive( Clone ) ]
2776+ struct CharEscapeDefault impl Fn = |c: char | -> char :: EscapeDefault {
2777+ c. escape_default( )
2778+ } ;
2779+
2780+ #[ derive( Clone ) ]
2781+ struct IsWhitespace impl Fn = |c: char | -> bool {
2782+ c. is_whitespace( )
2783+ } ;
2784+
2785+ #[ derive( Clone ) ]
2786+ struct IsAsciiWhitespace impl Fn = |byte: & u8 | -> bool {
2787+ byte. is_ascii_whitespace( )
2788+ } ;
2789+
2790+ #[ derive( Clone ) ]
2791+ struct IsNotEmpty impl <' a, ' b> Fn = |s: & ' a & ' b str | -> bool {
2792+ !s. is_empty( )
2793+ } ;
2794+
2795+ #[ derive( Clone ) ]
2796+ struct BytesIsNotEmpty impl <' a, ' b> Fn = |s: & ' a & ' b [ u8 ] | -> bool {
2797+ !s. is_empty( )
2798+ } ;
2799+
2800+ #[ derive( Clone ) ]
2801+ struct UnsafeBytesToStr impl <' a> Fn = |bytes: & ' a [ u8 ] | -> & ' a str {
2802+ // SAFETY: not safe
2803+ unsafe { from_utf8_unchecked( bytes) }
2804+ } ;
2805+ }
27762806
27772807// This is required to make `impl From<&str> for Box<dyn Error>` and `impl<E> From<E> for Box<dyn Error>` not overlap.
27782808#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments