@@ -5,7 +5,10 @@ use crate::cmp;
5
5
use crate :: hash:: { Hash , Hasher } ;
6
6
use crate :: rc:: Rc ;
7
7
use crate :: sync:: Arc ;
8
- use crate :: needle:: { Hay , Haystack , Needle , Span , Searcher , ReverseSearcher , Consumer , ReverseConsumer } ;
8
+ use crate :: needle:: {
9
+ ext, Hay , Haystack , Needle , Span , Searcher , ReverseSearcher ,
10
+ Consumer , ReverseConsumer , DoubleEndedConsumer ,
11
+ } ;
9
12
10
13
use crate :: sys:: os_str:: { Buf , Slice , OsStrSearcher } ;
11
14
use crate :: sys_common:: { AsInner , IntoInner , FromInner } ;
@@ -678,6 +681,326 @@ impl OsStr {
678
681
let boxed = unsafe { Box :: from_raw ( Box :: into_raw ( self ) as * mut Slice ) } ;
679
682
OsString { inner : Buf :: from_box ( boxed) }
680
683
}
684
+
685
+ /// Returns `true` if the given needle matches a prefix of this `OsStr`.
686
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
687
+ #[ inline]
688
+ pub fn starts_with < ' a , P > ( & ' a self , needle : P ) -> bool
689
+ where
690
+ P : Needle < & ' a OsStr > ,
691
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
692
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
693
+ {
694
+ ext:: starts_with ( self , needle)
695
+ }
696
+
697
+ /// Returns `true` if the given needle matches a suffix of this `OsStr`.
698
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
699
+ #[ inline]
700
+ pub fn ends_with < ' a , P > ( & ' a self , needle : P ) -> bool
701
+ where
702
+ P : Needle < & ' a OsStr > ,
703
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
704
+ P :: Consumer : ReverseConsumer < OsStr > ,
705
+ {
706
+ ext:: ends_with ( self , needle)
707
+ }
708
+
709
+ /// Returns `true` if the given needle matches a sub-slice of this `OsStr`.
710
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
711
+ #[ inline]
712
+ pub fn contains < ' a , P > ( & ' a self , needle : P ) -> bool
713
+ where
714
+ P : Needle < & ' a OsStr > ,
715
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
716
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
717
+ {
718
+ ext:: contains ( self , needle)
719
+ }
720
+
721
+ /// Returns the start index of first slice of this `OsStr` that matches the
722
+ /// needle.
723
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
724
+ #[ inline]
725
+ pub fn find < ' a , P > ( & ' a self , needle : P ) -> Option < usize >
726
+ where
727
+ P : Needle < & ' a OsStr > ,
728
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
729
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
730
+ {
731
+ ext:: find ( self , needle)
732
+ }
733
+
734
+ /// Returns the start index of last slice of this `OsStr` that matches the
735
+ /// needle.
736
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
737
+ #[ inline]
738
+ pub fn rfind < ' a , P > ( & ' a self , needle : P ) -> Option < usize >
739
+ where
740
+ P : Needle < & ' a OsStr > ,
741
+ P :: Searcher : ReverseSearcher < OsStr > ,
742
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
743
+ {
744
+ ext:: rfind ( self , needle)
745
+ }
746
+
747
+ /// Returns the index range of first slice of this `OsStr` that matches the
748
+ /// needle.
749
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
750
+ #[ inline]
751
+ pub fn find_range < ' a , P > ( & ' a self , needle : P ) -> Option < ops:: Range < usize > >
752
+ where
753
+ P : Needle < & ' a OsStr > ,
754
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
755
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
756
+ {
757
+ ext:: find_range ( self , needle)
758
+ }
759
+
760
+ /// Returns the start index of last slice of this `OsStr` that matches the
761
+ /// needle.
762
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
763
+ #[ inline]
764
+ pub fn rfind_range < ' a , P > ( & ' a self , needle : P ) -> Option < ops:: Range < usize > >
765
+ where
766
+ P : Needle < & ' a OsStr > ,
767
+ P :: Searcher : ReverseSearcher < OsStr > ,
768
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
769
+ {
770
+ ext:: rfind_range ( self , needle)
771
+ }
772
+
773
+ /// Returns an `OsStr` slice with all prefixes that match the needle
774
+ /// repeatedly removed.
775
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
776
+ #[ inline]
777
+ pub fn trim_start_matches < ' a , P > ( & ' a self , needle : P ) -> & ' a OsStr
778
+ where
779
+ P : Needle < & ' a OsStr > ,
780
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
781
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
782
+ {
783
+ ext:: trim_start ( self , needle)
784
+ }
785
+
786
+ /// Returns an `OsStr` slice with all suffixes that match the needle
787
+ /// repeatedly removed.
788
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
789
+ #[ inline]
790
+ pub fn trim_end_matches < ' a , P > ( & ' a self , needle : P ) -> & ' a OsStr
791
+ where
792
+ P : Needle < & ' a OsStr > ,
793
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
794
+ P :: Consumer : ReverseConsumer < OsStr > ,
795
+ {
796
+ ext:: trim_end ( self , needle)
797
+ }
798
+
799
+ /// Returns an `OsStr` slice with all prefixes and suffixes that match the
800
+ /// needle repeatedly removed.
801
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
802
+ #[ inline]
803
+ pub fn trim_matches < ' a , P > ( & ' a self , needle : P ) -> & ' a OsStr
804
+ where
805
+ P : Needle < & ' a OsStr > ,
806
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
807
+ P :: Consumer : DoubleEndedConsumer < OsStr > ,
808
+ {
809
+ ext:: trim ( self , needle)
810
+ }
811
+
812
+ /// An iterator over the disjoint matches of the needle within the given
813
+ /// `OsStr`.
814
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
815
+ #[ inline]
816
+ pub fn matches < ' a , P > ( & ' a self , needle : P ) -> ext:: Matches < & ' a OsStr , P :: Searcher >
817
+ where
818
+ P : Needle < & ' a OsStr > ,
819
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
820
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
821
+ {
822
+ ext:: matches ( self , needle)
823
+ }
824
+
825
+ /// An iterator over the disjoint matches of the needle within the given
826
+ /// `OsStr`, yielded in reverse order.
827
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
828
+ #[ inline]
829
+ pub fn rmatches < ' a , P > ( & ' a self , needle : P ) -> ext:: RMatches < & ' a OsStr , P :: Searcher >
830
+ where
831
+ P : Needle < & ' a OsStr > ,
832
+ P :: Searcher : ReverseSearcher < OsStr > ,
833
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
834
+ {
835
+ ext:: rmatches ( self , needle)
836
+ }
837
+
838
+ /// An iterator over the disjoint matches of a needle within this `OsStr`
839
+ /// as well as the index that the match starts at.
840
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
841
+ #[ inline]
842
+ pub fn match_indices < ' a , P > ( & ' a self , needle : P ) -> ext:: MatchIndices < & ' a OsStr , P :: Searcher >
843
+ where
844
+ P : Needle < & ' a OsStr > ,
845
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
846
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
847
+ {
848
+ ext:: match_indices ( self , needle)
849
+ }
850
+
851
+ /// An iterator over the disjoint matches of a needle within this `OsStr`,
852
+ /// yielded in reverse order along with the index of the match.
853
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
854
+ #[ inline]
855
+ pub fn rmatch_indices < ' a , P > ( & ' a self , needle : P ) -> ext:: RMatchIndices < & ' a OsStr , P :: Searcher >
856
+ where
857
+ P : Needle < & ' a OsStr > ,
858
+ P :: Searcher : ReverseSearcher < OsStr > ,
859
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
860
+ {
861
+ ext:: rmatch_indices ( self , needle)
862
+ }
863
+
864
+ /// An iterator over the disjoint matches of a needle within this `OsStr`
865
+ /// as well as the index ranges of each match.
866
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
867
+ #[ inline]
868
+ pub fn match_ranges < ' a , P > ( & ' a self , needle : P ) -> ext:: MatchRanges < & ' a OsStr , P :: Searcher >
869
+ where
870
+ P : Needle < & ' a OsStr > ,
871
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
872
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
873
+ {
874
+ ext:: match_ranges ( self , needle)
875
+ }
876
+
877
+ /// An iterator over the disjoint matches of a needle within this `OsStr`,
878
+ /// yielded in reverse order along with the index ranges of each match.
879
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
880
+ #[ inline]
881
+ pub fn rmatch_ranges < ' a , P > ( & ' a self , needle : P ) -> ext:: RMatchRanges < & ' a OsStr , P :: Searcher >
882
+ where
883
+ P : Needle < & ' a OsStr > ,
884
+ P :: Searcher : ReverseSearcher < OsStr > ,
885
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
886
+ {
887
+ ext:: rmatch_ranges ( self , needle)
888
+ }
889
+
890
+ /// An iterator over slices of this `OsStr`, separated by parts matched by
891
+ /// the needle.
892
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
893
+ #[ inline]
894
+ pub fn split < ' a , P > ( & ' a self , needle : P ) -> ext:: Split < & ' a OsStr , P :: Searcher >
895
+ where
896
+ P : Needle < & ' a OsStr > ,
897
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
898
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
899
+ {
900
+ ext:: split ( self , needle)
901
+ }
902
+
903
+ /// An iterator over slices of this `OsStr`, separated by parts matched by
904
+ /// the needle and yielded in reverse order.
905
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
906
+ #[ inline]
907
+ pub fn rsplit < ' a , P > ( & ' a self , needle : P ) -> ext:: RSplit < & ' a OsStr , P :: Searcher >
908
+ where
909
+ P : Needle < & ' a OsStr > ,
910
+ P :: Searcher : ReverseSearcher < OsStr > ,
911
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
912
+ {
913
+ ext:: rsplit ( self , needle)
914
+ }
915
+
916
+ /// An iterator over slices of this `OsStr`, separated by parts matched by
917
+ /// the needle.
918
+ ///
919
+ /// Equivalent to [`split`], except that the trailing slice is skipped if
920
+ /// empty.
921
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
922
+ #[ inline]
923
+ pub fn split_terminator < ' a , P > ( & ' a self , needle : P )
924
+ -> ext:: SplitTerminator < & ' a OsStr , P :: Searcher >
925
+ where
926
+ P : Needle < & ' a OsStr > ,
927
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
928
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
929
+ {
930
+ ext:: split_terminator ( self , needle)
931
+ }
932
+
933
+ /// An iterator over slices of this `OsStr`, separated by parts matched by
934
+ /// the needle and yielded in reverse order.
935
+ ///
936
+ /// Equivalent to [`rsplit`], except that the trailing slice is skipped if
937
+ /// empty.
938
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
939
+ #[ inline]
940
+ pub fn rsplit_terminator < ' a , P > ( & ' a self , needle : P )
941
+ -> ext:: RSplitTerminator < & ' a OsStr , P :: Searcher >
942
+ where
943
+ P : Needle < & ' a OsStr > ,
944
+ P :: Searcher : ReverseSearcher < OsStr > ,
945
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
946
+ {
947
+ ext:: rsplit_terminator ( self , needle)
948
+ }
949
+
950
+ /// An iterator over slices of the given `OsStr`, separated by a needle,
951
+ /// restricted to returning at most `n` items.
952
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
953
+ #[ inline]
954
+ pub fn splitn < ' a , P > ( & ' a self , n : usize , needle : P ) -> ext:: SplitN < & ' a OsStr , P :: Searcher >
955
+ where
956
+ P : Needle < & ' a OsStr > ,
957
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
958
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
959
+ {
960
+ ext:: splitn ( self , n, needle)
961
+ }
962
+
963
+ /// An iterator over slices of the given `OsStr`, separated by a needle,
964
+ /// starting from the end of the `OsStr`, restricted to returning at most
965
+ /// `n` items.
966
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
967
+ #[ inline]
968
+ pub fn rsplitn < ' a , P > ( & ' a self , n : usize , needle : P ) -> ext:: RSplitN < & ' a OsStr , P :: Searcher >
969
+ where
970
+ P : Needle < & ' a OsStr > ,
971
+ P :: Searcher : ReverseSearcher < OsStr > ,
972
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
973
+ {
974
+ ext:: rsplitn ( self , n, needle)
975
+ }
976
+
977
+ /// Replaces all matches of a needle with another `OsStr`.
978
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
979
+ #[ inline]
980
+ pub fn replace < ' s : ' a , ' a , P > ( & ' s self , from : P , to : & ' a OsStr ) -> OsString
981
+ where
982
+ P : Needle < & ' a OsStr > ,
983
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
984
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
985
+ {
986
+ let mut result = OsString :: with_capacity ( self . len ( ) ) ;
987
+ ext:: replace_with ( self , from, |_| to, |s| result. push ( s) ) ;
988
+ result
989
+ }
990
+
991
+ /// Replaces first N matches of a needle with another `OsStr`.
992
+ #[ unstable( feature = "os_str_needle_methods" , issue = "56345" ) ]
993
+ #[ inline]
994
+ pub fn replacen < ' s : ' a , ' a , P > ( & ' s self , from : P , to : & ' a OsStr , count : usize ) -> OsString
995
+ where
996
+ P : Needle < & ' a OsStr > ,
997
+ P :: Searcher : Searcher < OsStr > , // FIXME: RFC 2089
998
+ P :: Consumer : Consumer < OsStr > , // FIXME: RFC 2089
999
+ {
1000
+ let mut result = OsString :: with_capacity ( self . len ( ) ) ;
1001
+ ext:: replacen_with ( self , from, |_| to, count, |s| result. push ( s) ) ;
1002
+ result
1003
+ }
681
1004
}
682
1005
683
1006
#[ stable( feature = "box_from_os_str" , since = "1.17.0" ) ]
@@ -1412,3 +1735,192 @@ impl<'h, 'p> Needle<&'h OsStr> for &'p str {
1412
1735
NaiveSearcher :: new ( self . as_bytes ( ) )
1413
1736
}
1414
1737
}
1738
+
1739
+ #[ cfg( test) ]
1740
+ mod needle_tests {
1741
+ use super :: * ;
1742
+
1743
+ #[ cfg( windows) ]
1744
+ use os:: windows:: ffi:: OsStringExt ;
1745
+ #[ cfg( unix) ]
1746
+ use os:: unix:: ffi:: OsStrExt ;
1747
+
1748
+ #[ test]
1749
+ #[ cfg( any( unix, target_os = "redox" , target_arch = "wasm32" ) ) ]
1750
+ fn test_trim ( ) {
1751
+ assert_eq ! (
1752
+ OsStr :: from_bytes( b"\xaa \xbb \xaa \xcc \xaa \xbb \xaa " )
1753
+ . trim_start_matches( OsStr :: from_bytes( b"\xaa " ) ) ,
1754
+ OsStr :: from_bytes( b"\xbb \xaa \xcc \xaa \xbb \xaa " ) ,
1755
+ ) ;
1756
+ assert_eq ! (
1757
+ OsStr :: from_bytes( b"\xaa \xbb \xaa \xcc \xaa \xbb \xaa " )
1758
+ . trim_end_matches( OsStr :: from_bytes( b"\xaa " ) ) ,
1759
+ OsStr :: from_bytes( b"\xaa \xbb \xaa \xcc \xaa \xbb " ) ,
1760
+ ) ;
1761
+ }
1762
+
1763
+ #[ test]
1764
+ #[ cfg( windows) ]
1765
+ fn test_trim_start_low_surrogate ( ) {
1766
+ let pat = OsString :: from_wide ( & [ 0xdc00 ] ) ;
1767
+ let a = & OsStr :: new ( "\u{10000} aaa" ) [ 2 ..] ;
1768
+ assert_eq ! ( a. trim_start_matches( & pat) , OsStr :: new( "aaa" ) ) ;
1769
+
1770
+ let b = OsString :: from_wide ( & [ 0xd800 , 0xdc00 , 0xdc00 , 0x62 , 0x62 , 0x62 ] ) ;
1771
+ assert_eq ! ( b[ 2 ..] . trim_start_matches( & pat) , OsStr :: new( "bbb" ) ) ;
1772
+
1773
+ let c = OsString :: from_wide ( & [ 0xdc00 , 0xdc00 , 0x63 , 0x63 , 0x63 ] ) ;
1774
+ assert_eq ! ( c. trim_start_matches( & pat) , OsStr :: new( "ccc" ) ) ;
1775
+
1776
+ let d = & OsStr :: new ( "\u{ffc00} ddd" ) [ 2 ..] ;
1777
+ assert_eq ! ( d. trim_start_matches( & pat) , OsStr :: new( "ddd" ) ) ;
1778
+
1779
+ let e = OsStr :: new ( "㰀eee" ) ;
1780
+ assert_eq ! ( e. trim_start_matches( & pat) , e) ;
1781
+ }
1782
+
1783
+ #[ test]
1784
+ #[ cfg( windows) ]
1785
+ fn test_trim_start_high_surrogate ( ) {
1786
+ let pat = OsString :: from_wide ( & [ 0xd800 ] ) ;
1787
+ let a = OsStr :: new ( "\u{10000} " ) ;
1788
+ assert_eq ! ( a. trim_start_matches( & pat) , & * OsString :: from_wide( & [ 0xdc00 ] ) ) ;
1789
+
1790
+ let b = OsString :: from_wide ( & [ 0xd800 , 0x62 , 0x62 , 0x62 ] ) ;
1791
+ assert_eq ! ( b. trim_start_matches( & pat) , OsStr :: new( "bbb" ) ) ;
1792
+
1793
+ let c = OsString :: from_wide ( & [ 0xd800 , 0xd800 , 0xdc00 , 0x63 , 0x63 , 0x63 ] ) ;
1794
+ assert_eq ! ( c. trim_start_matches( & pat) , OsStr :: new( "ccc" ) ) ;
1795
+ }
1796
+
1797
+ #[ test]
1798
+ #[ cfg( windows) ]
1799
+ fn test_trim_end_high_surrogate ( ) {
1800
+ let pat = OsString :: from_wide ( & [ 0xd800 ] ) ;
1801
+ let a = OsStr :: new ( "aaa\u{10000} " ) ;
1802
+ assert_eq ! ( a[ ..a. len( ) -2 ] . trim_end_matches( & pat) , OsStr :: new( "aaa" ) ) ;
1803
+
1804
+ let b = OsString :: from_wide ( & [ 0x62 , 0x62 , 0x62 , 0xd800 , 0xd800 , 0xdc00 ] ) ;
1805
+ assert_eq ! ( b[ ..b. len( ) -2 ] . trim_end_matches( & pat) , OsStr :: new( "bbb" ) ) ;
1806
+
1807
+ let c = OsString :: from_wide ( & [ 0x63 , 0x63 , 0x63 , 0xd800 , 0xd800 ] ) ;
1808
+ assert_eq ! ( c. trim_end_matches( & pat) , OsStr :: new( "ccc" ) ) ;
1809
+
1810
+ let d = OsStr :: new ( "ddd\u{103ff} " ) ;
1811
+ assert_eq ! ( d[ ..d. len( ) -2 ] . trim_end_matches( & pat) , OsStr :: new( "ddd" ) ) ;
1812
+
1813
+ let e = OsStr :: new ( "eee\u{11000} " ) ;
1814
+ let e = & e[ ..e. len ( ) -2 ] ;
1815
+ assert_eq ! ( e. trim_end_matches( & pat) , e) ;
1816
+
1817
+ let f = OsString :: from_wide ( & [ 0x66 , 0x66 , 0x66 , 0xdc00 ] ) ;
1818
+ assert_eq ! ( f. trim_end_matches( & pat) , & * f) ;
1819
+ }
1820
+
1821
+
1822
+ #[ test]
1823
+ #[ cfg( windows) ]
1824
+ fn test_trim_end_low_surrogate ( ) {
1825
+ let pat = OsString :: from_wide ( & [ 0xdc00 ] ) ;
1826
+ let a = OsStr :: new ( "\u{10000} " ) ;
1827
+ assert_eq ! ( a. trim_end_matches( & pat) , & * OsString :: from_wide( & [ 0xd800 ] ) ) ;
1828
+
1829
+ let b = OsString :: from_wide ( & [ 0x62 , 0x62 , 0x62 , 0xdc00 ] ) ;
1830
+ assert_eq ! ( b. trim_end_matches( & pat) , OsStr :: new( "bbb" ) ) ;
1831
+
1832
+ let c = OsString :: from_wide ( & [ 0x63 , 0x63 , 0x63 , 0xdbff , 0xdc00 , 0xdc00 ] ) ;
1833
+ assert_eq ! ( c. trim_end_matches( & pat) , & c[ ..c. len( ) -3 ] ) ;
1834
+ }
1835
+
1836
+ #[ test]
1837
+ #[ cfg( windows) ]
1838
+ fn test_match_string_with_surrogates ( ) {
1839
+ unsafe {
1840
+ let haystack = & OsStr :: new ( "\u{10000} a\u{10000} a\u{10000} \u{10000} " ) [ 2 ..16 ] ;
1841
+ // 0..3 = U+DC00
1842
+ // 3..4 = 'a'
1843
+ // 4..6 = U+D800
1844
+ // 6..8 = U+DC00
1845
+ // 8..9 = 'a'
1846
+ // 9..11 = U+D800
1847
+ // 11..13 = U+DC00
1848
+ // 13..16 = U+D800
1849
+
1850
+ let pat = "a" ;
1851
+ let matched_pat = OsStr :: new ( pat) ;
1852
+ assert_eq ! ( haystack. match_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1853
+ ( 3 ..4 , matched_pat) ,
1854
+ ( 8 ..9 , matched_pat) ,
1855
+ ] ) ;
1856
+ assert_eq ! ( haystack. rmatch_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1857
+ ( 8 ..9 , matched_pat) ,
1858
+ ( 3 ..4 , matched_pat) ,
1859
+ ] ) ;
1860
+
1861
+ let pat = OsString :: from_wide ( & [ 0xdc00 , 0x61 ] ) ;
1862
+ assert_eq ! ( haystack. match_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1863
+ ( 0 ..4 , & * pat) ,
1864
+ ( 6 ..9 , & * pat) ,
1865
+ ] ) ;
1866
+ assert_eq ! ( haystack. rmatch_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1867
+ ( 6 ..9 , & * pat) ,
1868
+ ( 0 ..4 , & * pat) ,
1869
+ ] ) ;
1870
+
1871
+ let pat = OsString :: from_wide ( & [ 0x61 , 0xd800 ] ) ;
1872
+ assert_eq ! ( haystack. match_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1873
+ ( 3 ..6 , & * pat) ,
1874
+ ( 8 ..11 , & * pat) ,
1875
+ ] ) ;
1876
+ assert_eq ! ( haystack. rmatch_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1877
+ ( 8 ..11 , & * pat) ,
1878
+ ( 3 ..6 , & * pat) ,
1879
+ ] ) ;
1880
+
1881
+ let pat = "\u{10000} " ;
1882
+ let matched_pat = OsStr :: new ( pat) ;
1883
+ assert_eq ! ( haystack. match_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1884
+ ( 4 ..8 , matched_pat) ,
1885
+ ( 9 ..13 , matched_pat) ,
1886
+ ] ) ;
1887
+ assert_eq ! ( haystack. rmatch_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1888
+ ( 9 ..13 , matched_pat) ,
1889
+ ( 4 ..8 , matched_pat) ,
1890
+ ] ) ;
1891
+
1892
+ let pat = OsString :: from_wide ( & [ 0xd800 ] ) ;
1893
+ assert_eq ! ( haystack. match_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1894
+ ( 4 ..6 , & * pat) ,
1895
+ ( 9 ..11 , & * pat) ,
1896
+ ( 13 ..16 , & * pat) ,
1897
+ ] ) ;
1898
+ assert_eq ! ( haystack. rmatch_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1899
+ ( 13 ..16 , & * pat) ,
1900
+ ( 9 ..11 , & * pat) ,
1901
+ ( 4 ..6 , & * pat) ,
1902
+ ] ) ;
1903
+
1904
+ let pat = OsString :: from_wide ( & [ 0xdc00 ] ) ;
1905
+ assert_eq ! ( haystack. match_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1906
+ ( 0 ..3 , & * pat) ,
1907
+ ( 6 ..8 , & * pat) ,
1908
+ ( 11 ..13 , & * pat) ,
1909
+ ] ) ;
1910
+ assert_eq ! ( haystack. rmatch_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1911
+ ( 11 ..13 , & * pat) ,
1912
+ ( 6 ..8 , & * pat) ,
1913
+ ( 0 ..3 , & * pat) ,
1914
+ ] ) ;
1915
+
1916
+ let pat = OsString :: from_wide ( & [ 0xdc00 , 0xd800 ] ) ;
1917
+ assert_eq ! ( haystack. match_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1918
+ ( 11 ..16 , & * pat) ,
1919
+ ] ) ;
1920
+ assert_eq ! ( haystack. rmatch_ranges( pat) . collect:: <Vec <_>>( ) , vec![
1921
+ ( 11 ..16 , & * pat) ,
1922
+ ] ) ;
1923
+ }
1924
+ }
1925
+ }
1926
+
0 commit comments