1 use core::char::from_u32;
5 assert!(b"".is_ascii());
6 assert!(b"banana\0\x7F".is_ascii());
7 assert!(b"banana\0\x7F".iter().all(|b| b.is_ascii()));
8 assert!(!b"Vi\xe1\xbb\x87t Nam".is_ascii());
9 assert!(!b"Vi\xe1\xbb\x87t Nam".iter().all(|b| b.is_ascii()));
10 assert!(!b"\xe1\xbb\x87".iter().any(|b| b.is_ascii()));
12 assert!("".is_ascii());
13 assert!("banana\0\u{7F}".is_ascii());
14 assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii()));
15 assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii()));
16 assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii()));
20 fn test_to_ascii_uppercase() {
21 assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL");
22 assert_eq!("hıKß".to_ascii_uppercase(), "HıKß");
26 if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } else { i };
28 (from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
29 (from_u32(upper).unwrap()).to_string()
35 fn test_to_ascii_lowercase() {
36 assert_eq!("url()URL()uRl()Ürl".to_ascii_lowercase(), "url()url()url()Ürl");
37 // Dotted capital I, Kelvin sign, Sharp S.
38 assert_eq!("HİKß".to_ascii_lowercase(), "hİKß");
42 if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i };
44 (from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
45 (from_u32(lower).unwrap()).to_string()
51 fn test_make_ascii_lower_case() {
53 ($from: expr, $to: expr) => {{
55 x.make_ascii_lowercase();
66 test!(b"H\xc3\x89".to_vec(), b"h\xc3\x89");
67 test!("HİKß".to_string(), "hİKß");
71 fn test_make_ascii_upper_case() {
73 ($from: expr, $to: expr) => {{
75 x.make_ascii_uppercase();
86 test!(b"h\xc3\xa9".to_vec(), b"H\xc3\xa9");
87 test!("hıKß".to_string(), "HıKß");
89 let mut x = "Hello".to_string();
90 x[..3].make_ascii_uppercase(); // Test IndexMut on String.
91 assert_eq!(x, "HELlo")
95 fn test_eq_ignore_ascii_case() {
96 assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl"));
97 assert!(!"Ürl".eq_ignore_ascii_case("ürl"));
98 // Dotted capital I, Kelvin sign, Sharp S.
99 assert!("HİKß".eq_ignore_ascii_case("hİKß"));
100 assert!(!"İ".eq_ignore_ascii_case("i"));
101 assert!(!"K".eq_ignore_ascii_case("k"));
102 assert!(!"ß".eq_ignore_ascii_case("s"));
106 if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i };
108 (from_u32(i).unwrap())
110 .eq_ignore_ascii_case(&from_u32(lower).unwrap().to_string())
116 fn inference_works() {
117 let x = "a".to_string();
118 let _ = x.eq_ignore_ascii_case("A");
121 // Shorthands used by the is_ascii_* tests.
122 macro_rules! assert_all {
123 ($what:ident, $($str:tt),+) => {{
125 for b in $str.chars() {
127 panic!("expected {}({}) but it isn't",
128 stringify!($what), b);
131 for b in $str.as_bytes().iter() {
133 panic!("expected {}(0x{:02x})) but it isn't",
134 stringify!($what), b);
139 ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+))
141 macro_rules! assert_none {
142 ($what:ident, $($str:tt),+) => {{
144 for b in $str.chars() {
146 panic!("expected not-{}({}) but it is",
147 stringify!($what), b);
150 for b in $str.as_bytes().iter() {
152 panic!("expected not-{}(0x{:02x})) but it is",
153 stringify!($what), b);
158 ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+))
162 fn test_is_ascii_alphabetic() {
166 "abcdefghijklmnopqrstuvwxyz",
167 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
172 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
174 "\x00\x01\x02\x03\x04\x05\x06\x07",
175 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
176 "\x10\x11\x12\x13\x14\x15\x16\x17",
177 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
183 fn test_is_ascii_uppercase() {
184 assert_all!(is_ascii_uppercase, "", "ABCDEFGHIJKLMNOQPRSTUVWXYZ",);
187 "abcdefghijklmnopqrstuvwxyz",
189 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
191 "\x00\x01\x02\x03\x04\x05\x06\x07",
192 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
193 "\x10\x11\x12\x13\x14\x15\x16\x17",
194 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
200 fn test_is_ascii_lowercase() {
201 assert_all!(is_ascii_lowercase, "abcdefghijklmnopqrstuvwxyz",);
204 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
206 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
208 "\x00\x01\x02\x03\x04\x05\x06\x07",
209 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
210 "\x10\x11\x12\x13\x14\x15\x16\x17",
211 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
217 fn test_is_ascii_alphanumeric() {
219 is_ascii_alphanumeric,
221 "abcdefghijklmnopqrstuvwxyz",
222 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
226 is_ascii_alphanumeric,
227 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
229 "\x00\x01\x02\x03\x04\x05\x06\x07",
230 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
231 "\x10\x11\x12\x13\x14\x15\x16\x17",
232 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
238 fn test_is_ascii_digit() {
239 assert_all!(is_ascii_digit, "", "0123456789",);
242 "abcdefghijklmnopqrstuvwxyz",
243 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
244 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
246 "\x00\x01\x02\x03\x04\x05\x06\x07",
247 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
248 "\x10\x11\x12\x13\x14\x15\x16\x17",
249 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
255 fn test_is_ascii_hexdigit() {
256 assert_all!(is_ascii_hexdigit, "", "0123456789", "abcdefABCDEF",);
259 "ghijklmnopqrstuvwxyz",
260 "GHIJKLMNOQPRSTUVWXYZ",
261 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
263 "\x00\x01\x02\x03\x04\x05\x06\x07",
264 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
265 "\x10\x11\x12\x13\x14\x15\x16\x17",
266 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
272 fn test_is_ascii_punctuation() {
273 assert_all!(is_ascii_punctuation, "", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",);
275 is_ascii_punctuation,
276 "abcdefghijklmnopqrstuvwxyz",
277 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
280 "\x00\x01\x02\x03\x04\x05\x06\x07",
281 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
282 "\x10\x11\x12\x13\x14\x15\x16\x17",
283 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
289 fn test_is_ascii_graphic() {
293 "abcdefghijklmnopqrstuvwxyz",
294 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
296 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
301 "\x00\x01\x02\x03\x04\x05\x06\x07",
302 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
303 "\x10\x11\x12\x13\x14\x15\x16\x17",
304 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
310 fn test_is_ascii_whitespace() {
311 assert_all!(is_ascii_whitespace, "", " \t\n\x0c\r",);
314 "abcdefghijklmnopqrstuvwxyz",
315 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
317 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
318 "\x00\x01\x02\x03\x04\x05\x06\x07",
320 "\x10\x11\x12\x13\x14\x15\x16\x17",
321 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
327 fn test_is_ascii_control() {
331 "\x00\x01\x02\x03\x04\x05\x06\x07",
332 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
333 "\x10\x11\x12\x13\x14\x15\x16\x17",
334 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
339 "abcdefghijklmnopqrstuvwxyz",
340 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
342 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
347 // `is_ascii` does a good amount of pointer manipulation and has
348 // alignment-dependent computation. This is all sanity-checked via
349 // `debug_assert!`s, so we test various sizes/alignments thoroughly versus an
350 // "obviously correct" baseline function.
352 fn test_is_ascii_align_size_thoroughly() {
353 // The "obviously-correct" baseline mentioned above.
354 fn is_ascii_baseline(s: &[u8]) -> bool {
355 s.iter().all(|b| b.is_ascii())
358 // Helper to repeat `l` copies of `b0` followed by `l` copies of `b1`.
359 fn repeat_concat(b0: u8, b1: u8, l: usize) -> Vec<u8> {
360 use core::iter::repeat;
361 repeat(b0).take(l).chain(repeat(b1).take(l)).collect()
365 let iter = if cfg!(miri) { 0..20 } else { 0..100 };
375 repeat_concat(b'a', 0x80u8, i),
376 repeat_concat(0x80u8, b'a', i),
380 let cases = &[b"a".repeat(i), b"\x80".repeat(i), repeat_concat(b'a', 0x80u8, i)];
383 for pos in 0..=case.len() {
384 // Potentially misaligned head
385 let prefix = &case[pos..];
386 assert_eq!(is_ascii_baseline(prefix), prefix.is_ascii(),);
388 // Potentially misaligned tail
389 let suffix = &case[..case.len() - pos];
391 assert_eq!(is_ascii_baseline(suffix), suffix.is_ascii(),);
393 // Both head and tail are potentially misaligned
394 let mid = &case[(pos / 2)..(case.len() - (pos / 2))];
395 assert_eq!(is_ascii_baseline(mid), mid.is_ascii(),);
403 // test that the `is_ascii` methods of `char` and `u8` are usable in a const context
405 const CHAR_IS_ASCII: bool = 'a'.is_ascii();
406 assert!(CHAR_IS_ASCII);
408 const BYTE_IS_ASCII: bool = 97u8.is_ascii();
409 assert!(BYTE_IS_ASCII);
413 fn ascii_ctype_const() {
415 ( $( $fn:ident => [$a:ident, $A:ident, $nine:ident, $dot:ident, $space:ident]; )* ) => {
418 const CHAR_A_LOWER: bool = 'a'.$fn();
419 const CHAR_A_UPPER: bool = 'A'.$fn();
420 const CHAR_NINE: bool = '9'.$fn();
421 const CHAR_DOT: bool = '.'.$fn();
422 const CHAR_SPACE: bool = ' '.$fn();
424 const U8_A_LOWER: bool = b'a'.$fn();
425 const U8_A_UPPER: bool = b'A'.$fn();
426 const U8_NINE: bool = b'9'.$fn();
427 const U8_DOT: bool = b'.'.$fn();
428 const U8_SPACE: bool = b' '.$fn();
431 assert_eq!(CHAR_A_LOWER, $a);
432 assert_eq!(CHAR_A_UPPER, $A);
433 assert_eq!(CHAR_NINE, $nine);
434 assert_eq!(CHAR_DOT, $dot);
435 assert_eq!(CHAR_SPACE, $space);
437 assert_eq!(U8_A_LOWER, $a);
438 assert_eq!(U8_A_UPPER, $A);
439 assert_eq!(U8_NINE, $nine);
440 assert_eq!(U8_DOT, $dot);
441 assert_eq!(U8_SPACE, $space);
451 // 'a' 'A' '9' '.' ' '
452 is_ascii_alphabetic => [true, true, false, false, false];
453 is_ascii_uppercase => [false, true, false, false, false];
454 is_ascii_lowercase => [true, false, false, false, false];
455 is_ascii_alphanumeric => [true, true, true, false, false];
456 is_ascii_digit => [false, false, true, false, false];
457 is_ascii_hexdigit => [true, true, true, false, false];
458 is_ascii_punctuation => [false, false, false, true, false];
459 is_ascii_graphic => [true, true, true, true, false];
460 is_ascii_whitespace => [false, false, false, false, true];
461 is_ascii_control => [false, false, false, false, false];