@@ -983,7 +983,7 @@ impl str {
983983#[ cfg_attr( not( test) , rustc_diagnostic_item ="str_split_whitespace" ) ]
984984#[ inline]
985985pub 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]
10341034pub 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 ) ;
10421037SplitAsciiWhitespace { inner}
10431038}
10441039
@@ -1090,11 +1085,7 @@ impl str {
10901085#[ stable( feature ="rust1" , since ="1.0.0" ) ]
10911086#[ inline]
10921087pub 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" ) ]
26462637pub fn escape_debug ( & self ) ->EscapeDebug < ' _ > {
26472638let 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" ) ]
26972683pub 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" ) ]
27352721pub 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: & ' astr | ->& ' astr {
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& ' bstr | ->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 ] | ->& ' astr {
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" ) ]