@@ -9,6 +9,8 @@ for correctness, but some UTF-8 unsafe functions are also provided.
9
9
For some heavy-duty uses, we recommend trying std::rope.
10
10
*/
11
11
12
+ import option:: { some, none} ;
13
+
12
14
export
13
15
// Creating a string
14
16
from_bytes,
@@ -69,9 +71,11 @@ export
69
71
// Searching
70
72
index,
71
73
byte_index,
74
+ byte_index_from,
72
75
rindex,
73
76
find,
74
77
find_bytes,
78
+ find_from_bytes,
75
79
contains,
76
80
starts_with,
77
81
ends_with,
@@ -665,8 +669,8 @@ fn replace(s: str, from: str, to: str) : is_not_empty(from) -> str unsafe {
665
669
} else {
666
670
let idx;
667
671
alt find_bytes( s, from) {
668
- option :: some ( x) { idx = x; }
669
- option :: none { ret s; }
672
+ some ( x) { idx = x; }
673
+ none { ret s; }
670
674
}
671
675
let before = unsafe :: slice_bytes ( s, 0 u, idx as uint ) ;
672
676
let after = unsafe :: slice_bytes ( s, idx as uint + len_bytes ( from) ,
@@ -842,28 +846,34 @@ fn index(ss: str, cc: char) -> option<uint> {
842
846
843
847
// found here?
844
848
if ch == cc {
845
- ret option :: some ( cii) ;
849
+ ret some ( cii) ;
846
850
}
847
851
848
852
cii += 1 u;
849
853
bii = next;
850
854
}
851
855
852
856
// wasn't found
853
- ret option :: none;
857
+ ret none;
854
858
}
855
859
856
860
// Function: byte_index
857
861
//
858
862
// Returns the index of the first matching byte
859
863
// (as option some/none)
860
- fn byte_index ( s : str , b : u8 , start : uint ) -> option < uint > {
861
- let i = start, l = len_bytes ( s) ;
862
- while i < l {
863
- if s[ i] == b { ret some ( i) ; }
864
- i += 1 u;
865
- }
866
- ret none;
864
+ fn byte_index ( s : str , b : u8 ) -> option < uint > {
865
+ byte_index_from ( s, b, 0 u, len_bytes ( s) )
866
+ }
867
+
868
+ // Function: byte_index_from
869
+ //
870
+ // Returns the index of the first matching byte within the range [`start`,
871
+ // `end`).
872
+ // (as option some/none)
873
+ fn byte_index_from ( s : str , b : u8 , start : uint , end : uint ) -> option < uint > {
874
+ assert end <= len_bytes ( s) ;
875
+
876
+ str:: as_bytes ( s) { |v| vec:: position_from ( v, start, end) { |x| x == b } }
867
877
}
868
878
869
879
// Function: rindex
@@ -880,40 +890,50 @@ fn rindex(ss: str, cc: char) -> option<uint> {
880
890
881
891
// found here?
882
892
if ch == cc {
883
- ret option :: some ( cii) ;
893
+ ret some ( cii) ;
884
894
}
885
895
}
886
896
887
897
// wasn't found
888
- ret option :: none;
898
+ ret none;
889
899
}
890
900
891
901
//Function: find_bytes
892
902
//
893
903
// Find the char position of the first instance of one string
894
904
// within another, or return option::none
905
+ fn find_bytes ( haystack : str , needle : str ) -> option < uint > {
906
+ find_from_bytes ( haystack, needle, 0 u, len_bytes ( haystack) )
907
+ }
908
+
909
+ //Function: find_from_bytes
910
+ //
911
+ // Find the char position of the first instance of one string
912
+ // within another, or return option::none
895
913
//
896
914
// FIXME: Boyer-Moore should be significantly faster
897
- fn find_bytes ( haystack : str , needle : str ) -> option < uint > {
898
- let haystack_len = len_bytes ( haystack) ;
899
- let needle_len = len_bytes ( needle) ;
915
+ fn find_from_bytes ( haystack : str , needle : str , start : uint , end : uint )
916
+ -> option < uint > {
917
+ assert end <= len_bytes ( haystack) ;
918
+
919
+ let needle_len = len_bytes ( needle) ;
900
920
901
- if needle_len == 0 u { ret option :: some ( 0 u ) ; }
902
- if needle_len > haystack_len { ret option :: none; }
921
+ if needle_len == 0 u { ret some ( start ) ; }
922
+ if needle_len > end { ret none; }
903
923
904
924
fn match_at ( haystack : str , needle : str , ii : uint ) -> bool {
905
925
let jj = ii;
906
926
for c: u8 in needle { if haystack[ jj] != c { ret false ; } jj += 1 u; }
907
927
ret true;
908
928
}
909
929
910
- let ii = 0 u ;
911
- while ii <= haystack_len - needle_len {
912
- if match_at ( haystack, needle, ii) { ret option :: some ( ii) ; }
930
+ let ii = start ;
931
+ while ii <= end - needle_len {
932
+ if match_at ( haystack, needle, ii) { ret some ( ii) ; }
913
933
ii += 1 u;
914
934
}
915
935
916
- ret option :: none;
936
+ ret none;
917
937
}
918
938
919
939
// Function: find
@@ -922,8 +942,8 @@ fn find_bytes(haystack: str, needle: str) -> option<uint> {
922
942
// within another, or return option::none
923
943
fn find ( haystack : str , needle : str ) -> option < uint > {
924
944
alt find_bytes ( haystack, needle) {
925
- option :: none { ret option :: none; }
926
- option :: some ( nn) { ret option :: some ( b2c_pos ( haystack, nn) ) ; }
945
+ none { ret none; }
946
+ some ( nn) { ret some ( b2c_pos ( haystack, nn) ) ; }
927
947
}
928
948
}
929
949
@@ -1522,18 +1542,18 @@ mod tests {
1522
1542
1523
1543
#[ test]
1524
1544
fn test_index ( ) {
1525
- assert ( index ( "hello" , 'h' ) == option :: some ( 0 u) ) ;
1526
- assert ( index ( "hello" , 'e' ) == option :: some ( 1 u) ) ;
1527
- assert ( index ( "hello" , 'o' ) == option :: some ( 4 u) ) ;
1528
- assert ( index ( "hello" , 'z' ) == option :: none) ;
1545
+ assert ( index ( "hello" , 'h' ) == some ( 0 u) ) ;
1546
+ assert ( index ( "hello" , 'e' ) == some ( 1 u) ) ;
1547
+ assert ( index ( "hello" , 'o' ) == some ( 4 u) ) ;
1548
+ assert ( index ( "hello" , 'z' ) == none) ;
1529
1549
}
1530
1550
1531
1551
#[ test]
1532
1552
fn test_rindex ( ) {
1533
- assert ( rindex ( "hello" , 'l' ) == option :: some ( 3 u) ) ;
1534
- assert ( rindex ( "hello" , 'o' ) == option :: some ( 4 u) ) ;
1535
- assert ( rindex ( "hello" , 'h' ) == option :: some ( 0 u) ) ;
1536
- assert ( rindex ( "hello" , 'z' ) == option :: none) ;
1553
+ assert ( rindex ( "hello" , 'l' ) == some ( 3 u) ) ;
1554
+ assert ( rindex ( "hello" , 'o' ) == some ( 4 u) ) ;
1555
+ assert ( rindex ( "hello" , 'h' ) == some ( 0 u) ) ;
1556
+ assert ( rindex ( "hello" , 'z' ) == none) ;
1537
1557
}
1538
1558
1539
1559
#[ test]
@@ -1738,29 +1758,57 @@ mod tests {
1738
1758
#[ test]
1739
1759
fn test_find_bytes ( ) {
1740
1760
// byte positions
1741
- assert ( find_bytes ( "banana" , "apple pie" ) == option :: none) ;
1742
- assert ( find_bytes ( "" , "" ) == option :: some ( 0 u) ) ;
1761
+ assert ( find_bytes ( "banana" , "apple pie" ) == none) ;
1762
+ assert ( find_bytes ( "" , "" ) == some ( 0 u) ) ;
1743
1763
1744
1764
let data = "ประเทศไทย中华Việt Nam" ;
1745
- assert ( find_bytes ( data, "" ) == option:: some ( 0 u) ) ;
1746
- assert ( find_bytes ( data, "ประเ" ) == option:: some ( 0 u) ) ;
1747
- assert ( find_bytes ( data, "ะเ" ) == option:: some ( 6 u) ) ;
1748
- assert ( find_bytes ( data, "中华" ) == option:: some ( 27 u) ) ;
1749
- assert ( find_bytes ( data, "ไท华" ) == option:: none) ;
1765
+ assert ( find_bytes ( data, "" ) == some ( 0 u) ) ;
1766
+ assert ( find_bytes ( data, "ประเ" ) == some ( 0 u) ) ;
1767
+ assert ( find_bytes ( data, "ะเ" ) == some ( 6 u) ) ;
1768
+ assert ( find_bytes ( data, "中华" ) == some ( 27 u) ) ;
1769
+ assert ( find_bytes ( data, "ไท华" ) == none) ;
1770
+ }
1771
+
1772
+ #[ test]
1773
+ fn test_find_from_bytes ( ) {
1774
+ // byte positions
1775
+ assert ( find_from_bytes ( "" , "" , 0 u, 0 u) == some ( 0 u) ) ;
1776
+
1777
+ let data = "abcabc" ;
1778
+ assert find_from_bytes ( data, "ab" , 0 u, 6 u) == some ( 0 u) ;
1779
+ assert find_from_bytes ( data, "ab" , 2 u, 6 u) == some ( 3 u) ;
1780
+ assert find_from_bytes ( data, "ab" , 2 u, 4 u) == none;
1781
+
1782
+ let data = "ประเทศไทย中华Việt Nam" ;
1783
+ data += data;
1784
+ assert find_from_bytes ( data, "" , 0 u, 43 u) == some ( 0 u) ;
1785
+ assert find_from_bytes ( data, "" , 6 u, 43 u) == some ( 6 u) ;
1786
+
1787
+ assert find_from_bytes ( data, "ประ" , 0 u, 43 u) == some ( 0 u) ;
1788
+ assert find_from_bytes ( data, "ทศไ" , 0 u, 43 u) == some ( 12 u) ;
1789
+ assert find_from_bytes ( data, "ย中" , 0 u, 43 u) == some ( 24 u) ;
1790
+ assert find_from_bytes ( data, "iệt" , 0 u, 43 u) == some ( 34 u) ;
1791
+ assert find_from_bytes ( data, "Nam" , 0 u, 43 u) == some ( 40 u) ;
1792
+
1793
+ assert find_from_bytes ( data, "ประ" , 43 u, 86 u) == some ( 43 u) ;
1794
+ assert find_from_bytes ( data, "ทศไ" , 43 u, 86 u) == some ( 55 u) ;
1795
+ assert find_from_bytes ( data, "ย中" , 43 u, 86 u) == some ( 67 u) ;
1796
+ assert find_from_bytes ( data, "iệt" , 43 u, 86 u) == some ( 77 u) ;
1797
+ assert find_from_bytes ( data, "Nam" , 43 u, 86 u) == some ( 83 u) ;
1750
1798
}
1751
1799
1752
1800
#[ test]
1753
1801
fn test_find ( ) {
1754
1802
// char positions
1755
- assert ( find ( "banana" , "apple pie" ) == option :: none) ;
1756
- assert ( find ( "" , "" ) == option :: some ( 0 u) ) ;
1803
+ assert ( find ( "banana" , "apple pie" ) == none) ;
1804
+ assert ( find ( "" , "" ) == some ( 0 u) ) ;
1757
1805
1758
1806
let data = "ประเทศไทย中华Việt Nam" ;
1759
- assert ( find ( data, "" ) == option :: some ( 0 u) ) ;
1760
- assert ( find ( data, "ประเ" ) == option :: some ( 0 u) ) ;
1761
- assert ( find ( data, "ะเ" ) == option :: some ( 2 u) ) ;
1762
- assert ( find ( data, "中华" ) == option :: some ( 9 u) ) ;
1763
- assert ( find ( data, "ไท华" ) == option :: none) ;
1807
+ assert ( find ( data, "" ) == some ( 0 u) ) ;
1808
+ assert ( find ( data, "ประเ" ) == some ( 0 u) ) ;
1809
+ assert ( find ( data, "ะเ" ) == some ( 2 u) ) ;
1810
+ assert ( find ( data, "中华" ) == some ( 9 u) ) ;
1811
+ assert ( find ( data, "ไท华" ) == none) ;
1764
1812
}
1765
1813
1766
1814
#[ test]
0 commit comments