@@ -983,7 +983,7 @@ impl str {
983
983
#[ cfg_attr( not( test) , rustc_diagnostic_item = "str_split_whitespace" ) ]
984
984
#[ inline]
985
985
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 ) }
987
987
}
988
988
989
989
/// Splits a string slice by ASCII whitespace.
@@ -1032,13 +1032,8 @@ impl str {
1032
1032
#[ stable( feature = "split_ascii_whitespace" , since = "1.34.0" ) ]
1033
1033
#[ inline]
1034
1034
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 ) ;
1042
1037
SplitAsciiWhitespace { inner }
1043
1038
}
1044
1039
@@ -1090,11 +1085,7 @@ impl str {
1090
1085
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1091
1086
#[ inline]
1092
1087
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 ) )
1098
1089
}
1099
1090
1100
1091
/// An iterator over the lines of a string.
@@ -2645,19 +2636,14 @@ impl str {
2645
2636
#[ stable( feature = "str_escape" , since = "1.34.0" ) ]
2646
2637
pub fn escape_debug ( & self ) -> EscapeDebug < ' _ > {
2647
2638
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
+ }
2661
2647
}
2662
2648
2663
2649
/// Return an iterator that escapes each char in `self` with [`char::escape_default`].
@@ -2695,7 +2681,7 @@ impl str {
2695
2681
without modifying the original"]
2696
2682
#[ stable( feature = "str_escape" , since = "1.34.0" ) ]
2697
2683
pub fn escape_default ( & self ) -> EscapeDefault < ' _ > {
2698
- EscapeDefault { inner : self . chars ( ) . flat_map ( char :: escape_default ) }
2684
+ EscapeDefault { inner : self . chars ( ) . flat_map ( CharEscapeDefault ) }
2699
2685
}
2700
2686
2701
2687
/// Return an iterator that escapes each char in `self` with [`char::escape_unicode`].
@@ -2733,7 +2719,7 @@ impl str {
2733
2719
without modifying the original"]
2734
2720
#[ stable( feature = "str_escape" , since = "1.34.0" ) ]
2735
2721
pub fn escape_unicode ( & self ) -> EscapeUnicode < ' _ > {
2736
- EscapeUnicode { inner : self . chars ( ) . flat_map ( char :: escape_unicode ) }
2722
+ EscapeUnicode { inner : self . chars ( ) . flat_map ( CharEscapeUnicode ) }
2737
2723
}
2738
2724
}
2739
2725
@@ -2764,15 +2750,59 @@ impl Default for &mut str {
2764
2750
}
2765
2751
}
2766
2752
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
+ }
2776
2806
2777
2807
// This is required to make `impl From<&str> for Box<dyn Error>` and `impl<E> From<E> for Box<dyn Error>` not overlap.
2778
2808
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments