@@ -14,8 +14,8 @@ export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len,
14
14
char_at, bytes, is_ascii, shift_byte, pop_byte,
15
15
unsafe_from_byte, unsafe_from_bytes, from_char, char_range_at,
16
16
from_cstr, sbuf, as_buf, push_byte, utf8_char_width, safe_slice,
17
- contains, iter_chars, loop_chars , loop_chars_sub ,
18
- escape;
17
+ contains, iter_chars, chars_iter , bytes_iter ,
18
+ loop_chars , loop_chars_sub , escape, any , all , map , windowed ;
19
19
20
20
#[ abi = "cdecl" ]
21
21
native mod rustrt {
@@ -346,7 +346,6 @@ Function: iter_chars
346
346
347
347
Iterate over the characters in a string
348
348
*/
349
-
350
349
fn iter_chars ( s : str , it : fn ( char ) ) {
351
350
let pos = 0 u, len = byte_len ( s) ;
352
351
while ( pos < len) {
@@ -356,6 +355,34 @@ fn iter_chars(s: str, it: fn(char)) {
356
355
}
357
356
}
358
357
358
+ /*
359
+ Function: chars_iter
360
+
361
+ Iterate over the characters in a string
362
+
363
+ FIXME: A synonym to iter_chars
364
+ */
365
+ fn chars_iter ( ss : str , it : fn & ( char ) ) {
366
+ iter_chars ( ss, it)
367
+ }
368
+
369
+ /*
370
+ Function: bytes_iter
371
+
372
+ Iterate over the bytes in a string
373
+
374
+ FIXME: Should it really include the last byte '\0'?
375
+ */
376
+ fn bytes_iter ( ss : str , it : fn & ( u8 ) ) {
377
+ let pos = 0 u;
378
+ let len = byte_len ( ss) ;
379
+
380
+ while ( pos < len) {
381
+ it ( ss[ pos] ) ;
382
+ pos += 1 u;
383
+ }
384
+ }
385
+
359
386
/*
360
387
Function: loop_chars
361
388
@@ -1116,14 +1143,25 @@ fn escape(s: str) -> str {
1116
1143
/*
1117
1144
Function: all
1118
1145
1119
- Return true if a predicate matches all characters
1146
+ Return true if a predicate matches all characters or
1147
+ if the string contains no characters
1120
1148
1121
- If the string contains no characters
1149
+ // FIXME: a synonym to loop_chars
1122
1150
*/
1123
1151
fn all ( ss : str , ff : fn & ( char ) -> bool ) -> bool {
1124
1152
str:: loop_chars ( ss, ff)
1125
1153
}
1126
1154
1155
+ /*
1156
+ Function: any
1157
+
1158
+ Return true if a predicate matches any character
1159
+ (and false if it matches none or there are no characters)
1160
+ */
1161
+ fn any ( ss : str , pred : fn & ( char ) -> bool ) -> bool {
1162
+ !all ( ss, { |cc| !pred ( cc) } )
1163
+ }
1164
+
1127
1165
/*
1128
1166
Function: map
1129
1167
@@ -1139,6 +1177,26 @@ fn map(ss: str, ff: fn&(char) -> char) -> str {
1139
1177
ret result;
1140
1178
}
1141
1179
1180
+ /*
1181
+ Function: windowed
1182
+
1183
+ Create a vector of substrings of size `nn`
1184
+ */
1185
+ fn windowed ( nn : uint , ss : str ) -> [ str ] {
1186
+ let ww = [ ] ;
1187
+ let len = str:: char_len ( ss) ;
1188
+
1189
+ assert 1 u <= nn;
1190
+
1191
+ let ii = 0 u;
1192
+ while ii+nn <= len {
1193
+ let w = char_slice ( ss, ii, ii+nn ) ;
1194
+ vec:: push ( ww, w) ;
1195
+ ii += 1 u;
1196
+ }
1197
+
1198
+ ret ww;
1199
+ }
1142
1200
1143
1201
#[ cfg( test) ]
1144
1202
mod tests {
@@ -1590,6 +1648,39 @@ mod tests {
1590
1648
}
1591
1649
i += 1 ;
1592
1650
}
1651
+
1652
+ iter_chars ( "" ) { |ch| fail; } // should not fail
1653
+ }
1654
+
1655
+ #[ test]
1656
+ fn test_chars_iter ( ) {
1657
+ let i = 0 ;
1658
+ chars_iter ( "x\u03c0 y" ) { |ch|
1659
+ alt i {
1660
+ 0 { assert ch == 'x' ; }
1661
+ 1 { assert ch == '\u03c0' ; }
1662
+ 2 { assert ch == 'y' ; }
1663
+ }
1664
+ i += 1 ;
1665
+ }
1666
+
1667
+ chars_iter ( "" ) { |_ch| fail; } // should not fail
1668
+ }
1669
+
1670
+ #[ test]
1671
+ fn test_bytes_iter ( ) {
1672
+ let i = 0 ;
1673
+
1674
+ bytes_iter ( "xyz" ) { |bb|
1675
+ alt i {
1676
+ 0 { assert bb == 'x' as u8 ; }
1677
+ 1 { assert bb == 'y' as u8 ; }
1678
+ 2 { assert bb == 'z' as u8 ; }
1679
+ }
1680
+ i += 1 ;
1681
+ }
1682
+
1683
+ bytes_iter ( "" ) { |bb| assert bb == 0u8 ; }
1593
1684
}
1594
1685
1595
1686
#[ test]
@@ -1601,17 +1692,44 @@ mod tests {
1601
1692
}
1602
1693
1603
1694
#[ test]
1604
- fn test_map ( ) {
1695
+ fn test_map ( ) {
1605
1696
assert "" == map ( "" , char:: to_upper) ;
1606
1697
assert "YMCA" == map ( "ymca" , char:: to_upper) ;
1607
1698
}
1608
1699
1609
1700
#[ test]
1610
- fn test_all ( ) {
1701
+ fn test_all ( ) {
1611
1702
assert true == all ( "" , char:: is_uppercase) ;
1612
1703
assert false == all ( "ymca" , char:: is_uppercase) ;
1613
1704
assert true == all ( "YMCA" , char:: is_uppercase) ;
1614
1705
assert false == all ( "yMCA" , char:: is_uppercase) ;
1615
1706
assert false == all ( "YMCy" , char:: is_uppercase) ;
1616
1707
}
1708
+
1709
+ #[ test]
1710
+ fn test_any ( ) {
1711
+ assert false == any ( "" , char:: is_uppercase) ;
1712
+ assert false == any ( "ymca" , char:: is_uppercase) ;
1713
+ assert true == any ( "YMCA" , char:: is_uppercase) ;
1714
+ assert true == any ( "yMCA" , char:: is_uppercase) ;
1715
+ assert true == any ( "YMCy" , char:: is_uppercase) ;
1716
+ }
1717
+
1718
+ #[ test]
1719
+ fn test_windowed ( ) {
1720
+ let data = "ประเทศไทย中" ;
1721
+
1722
+ assert [ "ประ" , "ระเ" , "ะเท" , "เทศ" , "ทศไ" , "ศไท" , "ไทย" , "ทย中" ]
1723
+ == windowed ( 3 u, data) ;
1724
+
1725
+ assert [ data] == windowed ( 10 u, data) ;
1726
+
1727
+ assert [ ] == windowed ( 6 u, "abcd" ) ;
1728
+ }
1729
+
1730
+ #[ test]
1731
+ #[ should_fail]
1732
+ fn test_windowed_ ( ) {
1733
+ let _x = windowed ( 0 u, "abcd" ) ;
1734
+ }
1617
1735
}
0 commit comments