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_octdigit() {
256 assert_all!(is_ascii_octdigit, "", "01234567");
259 "abcdefghijklmnopqrstuvwxyz",
260 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
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_hexdigit() {
273 assert_all!(is_ascii_hexdigit, "", "0123456789", "abcdefABCDEF",);
276 "ghijklmnopqrstuvwxyz",
277 "GHIJKLMNOQPRSTUVWXYZ",
278 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
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_punctuation() {
290 assert_all!(is_ascii_punctuation, "", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",);
292 is_ascii_punctuation,
293 "abcdefghijklmnopqrstuvwxyz",
294 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
297 "\x00\x01\x02\x03\x04\x05\x06\x07",
298 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
299 "\x10\x11\x12\x13\x14\x15\x16\x17",
300 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
306 fn test_is_ascii_graphic() {
310 "abcdefghijklmnopqrstuvwxyz",
311 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
313 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
318 "\x00\x01\x02\x03\x04\x05\x06\x07",
319 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
320 "\x10\x11\x12\x13\x14\x15\x16\x17",
321 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
327 fn test_is_ascii_whitespace() {
328 assert_all!(is_ascii_whitespace, "", " \t\n\x0c\r",);
331 "abcdefghijklmnopqrstuvwxyz",
332 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
334 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
335 "\x00\x01\x02\x03\x04\x05\x06\x07",
337 "\x10\x11\x12\x13\x14\x15\x16\x17",
338 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
344 fn test_is_ascii_control() {
348 "\x00\x01\x02\x03\x04\x05\x06\x07",
349 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
350 "\x10\x11\x12\x13\x14\x15\x16\x17",
351 "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
356 "abcdefghijklmnopqrstuvwxyz",
357 "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
359 "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
364 // `is_ascii` does a good amount of pointer manipulation and has
365 // alignment-dependent computation. This is all sanity-checked via
366 // `debug_assert!`s, so we test various sizes/alignments thoroughly versus an
367 // "obviously correct" baseline function.
369 fn test_is_ascii_align_size_thoroughly() {
370 // The "obviously-correct" baseline mentioned above.
371 fn is_ascii_baseline(s: &[u8]) -> bool {
372 s.iter().all(|b| b.is_ascii())
375 // Helper to repeat `l` copies of `b0` followed by `l` copies of `b1`.
376 fn repeat_concat(b0: u8, b1: u8, l: usize) -> Vec<u8> {
377 use core::iter::repeat;
378 repeat(b0).take(l).chain(repeat(b1).take(l)).collect()
382 let iter = if cfg!(miri) { 0..20 } else { 0..100 };
392 repeat_concat(b'a', 0x80u8, i),
393 repeat_concat(0x80u8, b'a', i),
397 let cases = &[b"a".repeat(i), b"\x80".repeat(i), repeat_concat(b'a', 0x80u8, i)];
400 for pos in 0..=case.len() {
401 // Potentially misaligned head
402 let prefix = &case[pos..];
403 assert_eq!(is_ascii_baseline(prefix), prefix.is_ascii(),);
405 // Potentially misaligned tail
406 let suffix = &case[..case.len() - pos];
408 assert_eq!(is_ascii_baseline(suffix), suffix.is_ascii(),);
410 // Both head and tail are potentially misaligned
411 let mid = &case[(pos / 2)..(case.len() - (pos / 2))];
412 assert_eq!(is_ascii_baseline(mid), mid.is_ascii(),);
420 // test that the `is_ascii` methods of `char` and `u8` are usable in a const context
422 const CHAR_IS_ASCII: bool = 'a'.is_ascii();
423 assert!(CHAR_IS_ASCII);
425 const BYTE_IS_ASCII: bool = 97u8.is_ascii();
426 assert!(BYTE_IS_ASCII);
430 fn ascii_ctype_const() {
432 ( $( $fn:ident => [$a:ident, $A:ident, $nine:ident, $dot:ident, $space:ident]; )* ) => {
435 const CHAR_A_LOWER: bool = 'a'.$fn();
436 const CHAR_A_UPPER: bool = 'A'.$fn();
437 const CHAR_NINE: bool = '9'.$fn();
438 const CHAR_DOT: bool = '.'.$fn();
439 const CHAR_SPACE: bool = ' '.$fn();
441 const U8_A_LOWER: bool = b'a'.$fn();
442 const U8_A_UPPER: bool = b'A'.$fn();
443 const U8_NINE: bool = b'9'.$fn();
444 const U8_DOT: bool = b'.'.$fn();
445 const U8_SPACE: bool = b' '.$fn();
448 assert_eq!(CHAR_A_LOWER, $a);
449 assert_eq!(CHAR_A_UPPER, $A);
450 assert_eq!(CHAR_NINE, $nine);
451 assert_eq!(CHAR_DOT, $dot);
452 assert_eq!(CHAR_SPACE, $space);
454 assert_eq!(U8_A_LOWER, $a);
455 assert_eq!(U8_A_UPPER, $A);
456 assert_eq!(U8_NINE, $nine);
457 assert_eq!(U8_DOT, $dot);
458 assert_eq!(U8_SPACE, $space);
468 // 'a' 'A' '9' '.' ' '
469 is_ascii_alphabetic => [true, true, false, false, false];
470 is_ascii_uppercase => [false, true, false, false, false];
471 is_ascii_lowercase => [true, false, false, false, false];
472 is_ascii_alphanumeric => [true, true, true, false, false];
473 is_ascii_digit => [false, false, true, false, false];
474 is_ascii_octdigit => [false, false, false, false, false];
475 is_ascii_hexdigit => [true, true, true, false, false];
476 is_ascii_punctuation => [false, false, false, true, false];
477 is_ascii_graphic => [true, true, true, true, false];
478 is_ascii_whitespace => [false, false, false, false, true];
479 is_ascii_control => [false, false, false, false, false];