1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use std::cmp::Ordering::{Equal, Greater, Less};
13 use std::str::from_utf8;
19 assert!("foo" <= "foo");
20 assert!("foo" != "bar");
25 assert_eq!("hello".find('l'), Some(2));
26 assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
27 assert!("hello".find('x').is_none());
28 assert!("hello".find(|c:char| c == 'x').is_none());
29 assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
30 assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
35 assert_eq!("hello".rfind('l'), Some(3));
36 assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
37 assert!("hello".rfind('x').is_none());
38 assert!("hello".rfind(|c:char| c == 'x').is_none());
39 assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
40 assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
46 let s: String = empty.chars().collect();
48 let data = "ประเทศไทย中";
49 let s: String = data.chars().collect();
54 fn test_into_bytes() {
55 let data = String::from("asdf");
56 let buf = data.into_bytes();
57 assert_eq!(buf, b"asdf");
63 assert_eq!("".find(""), Some(0));
64 assert!("banana".find("apple pie").is_none());
67 assert_eq!(data[0..6].find("ab"), Some(0));
68 assert_eq!(data[2..6].find("ab"), Some(3 - 2));
69 assert!(data[2..4].find("ab").is_none());
71 let string = "ประเทศไทย中华Việt Nam";
72 let mut data = String::from(string);
73 data.push_str(string);
74 assert!(data.find("ไท华").is_none());
75 assert_eq!(data[0..43].find(""), Some(0));
76 assert_eq!(data[6..43].find(""), Some(6 - 6));
78 assert_eq!(data[0..43].find("ประ"), Some( 0));
79 assert_eq!(data[0..43].find("ทศไ"), Some(12));
80 assert_eq!(data[0..43].find("ย中"), Some(24));
81 assert_eq!(data[0..43].find("iệt"), Some(34));
82 assert_eq!(data[0..43].find("Nam"), Some(40));
84 assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
85 assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
86 assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
87 assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
88 assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
90 // find every substring -- assert that it finds it, or an earlier occurrence.
91 let string = "Việt Namacbaabcaabaaba";
92 for (i, ci) in string.char_indices() {
93 let ip = i + ci.len_utf8();
94 for j in string[ip..].char_indices()
96 .chain(Some(string.len() - ip))
98 let pat = &string[i..ip + j];
99 assert!(match string.find(pat) {
103 assert!(match string.rfind(pat) {
111 fn s(x: &str) -> String { x.to_string() }
113 macro_rules! test_concat {
114 ($expected: expr, $string: expr) => {
116 let s: String = $string.concat();
117 assert_eq!($expected, s);
123 fn test_concat_for_different_types() {
124 test_concat!("ab", vec![s("a"), s("b")]);
125 test_concat!("ab", vec!["a", "b"]);
126 test_concat!("ab", vec!["a", "b"]);
127 test_concat!("ab", vec![s("a"), s("b")]);
131 fn test_concat_for_different_lengths() {
132 let empty: &[&str] = &[];
133 test_concat!("", empty);
134 test_concat!("a", ["a"]);
135 test_concat!("ab", ["a", "b"]);
136 test_concat!("abc", ["", "a", "bc"]);
139 macro_rules! test_join {
140 ($expected: expr, $string: expr, $delim: expr) => {
142 let s = $string.join($delim);
143 assert_eq!($expected, s);
149 fn test_join_for_different_types() {
150 test_join!("a-b", ["a", "b"], "-");
151 let hyphen = "-".to_string();
152 test_join!("a-b", [s("a"), s("b")], &*hyphen);
153 test_join!("a-b", vec!["a", "b"], &*hyphen);
154 test_join!("a-b", &*vec!["a", "b"], "-");
155 test_join!("a-b", vec![s("a"), s("b")], "-");
159 fn test_join_for_different_lengths() {
160 let empty: &[&str] = &[];
161 test_join!("", empty, "-");
162 test_join!("a", ["a"], "-");
163 test_join!("a-b", ["a", "b"], "-");
164 test_join!("-a-bc", ["", "a", "bc"], "-");
168 fn test_unsafe_slice() {
169 assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
170 assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
171 assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
172 fn a_million_letter_a() -> String {
174 let mut rs = String::new();
176 rs.push_str("aaaaaaaaaa");
181 fn half_a_million_letter_a() -> String {
183 let mut rs = String::new();
185 rs.push_str("aaaaa");
190 let letters = a_million_letter_a();
191 assert_eq!(half_a_million_letter_a(),
192 unsafe { letters.slice_unchecked(0, 500000)});
196 fn test_starts_with() {
197 assert!(("".starts_with("")));
198 assert!(("abc".starts_with("")));
199 assert!(("abc".starts_with("a")));
200 assert!((!"a".starts_with("abc")));
201 assert!((!"".starts_with("abc")));
202 assert!((!"ödd".starts_with("-")));
203 assert!(("ödd".starts_with("öd")));
207 fn test_ends_with() {
208 assert!(("".ends_with("")));
209 assert!(("abc".ends_with("")));
210 assert!(("abc".ends_with("c")));
211 assert!((!"a".ends_with("abc")));
212 assert!((!"".ends_with("abc")));
213 assert!((!"ddö".ends_with("-")));
214 assert!(("ddö".ends_with("dö")));
219 assert!("".is_empty());
220 assert!(!"a".is_empty());
226 assert_eq!("".replace(a, "b"), "");
227 assert_eq!("a".replace(a, "b"), "b");
228 assert_eq!("ab".replace(a, "b"), "bb");
230 assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
231 assert_eq!(" test test ".replace(test, ""), " ");
235 fn test_replace_2a() {
236 let data = "ประเทศไทย中华";
237 let repl = "دولة الكويت";
240 let a2 = "دولة الكويتทศไทย中华";
241 assert_eq!(data.replace(a, repl), a2);
245 fn test_replace_2b() {
246 let data = "ประเทศไทย中华";
247 let repl = "دولة الكويت";
250 let b2 = "ปรدولة الكويتทศไทย中华";
251 assert_eq!(data.replace(b, repl), b2);
255 fn test_replace_2c() {
256 let data = "ประเทศไทย中华";
257 let repl = "دولة الكويت";
260 let c2 = "ประเทศไทยدولة الكويت";
261 assert_eq!(data.replace(c, repl), c2);
265 fn test_replace_2d() {
266 let data = "ประเทศไทย中华";
267 let repl = "دولة الكويت";
270 assert_eq!(data.replace(d, repl), data);
274 fn test_replace_pattern() {
275 let data = "abcdαβγδabcdαβγδ";
276 assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
277 assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
278 assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
279 assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
284 assert_eq!("ab", &"abc"[0..2]);
285 assert_eq!("bc", &"abc"[1..3]);
286 assert_eq!("", &"abc"[1..1]);
287 assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
289 let data = "ประเทศไทย中华";
290 assert_eq!("ป", &data[0..3]);
291 assert_eq!("ร", &data[3..6]);
292 assert_eq!("", &data[3..3]);
293 assert_eq!("华", &data[30..33]);
295 fn a_million_letter_x() -> String {
297 let mut rs = String::new();
299 rs.push_str("华华华华华华华华华华");
304 fn half_a_million_letter_x() -> String {
306 let mut rs = String::new();
308 rs.push_str("华华华华华");
313 let letters = a_million_letter_x();
314 assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
319 let ss = "中华Việt Nam";
321 assert_eq!("华", &ss[3..6]);
322 assert_eq!("Việt Nam", &ss[6..16]);
324 assert_eq!("ab", &"abc"[0..2]);
325 assert_eq!("bc", &"abc"[1..3]);
326 assert_eq!("", &"abc"[1..1]);
328 assert_eq!("中", &ss[0..3]);
329 assert_eq!("华V", &ss[3..7]);
330 assert_eq!("", &ss[3..3]);
345 fn test_slice_fail() {
350 fn test_slice_from() {
351 assert_eq!(&"abcd"[0..], "abcd");
352 assert_eq!(&"abcd"[2..], "cd");
353 assert_eq!(&"abcd"[4..], "");
357 assert_eq!(&"abcd"[..0], "");
358 assert_eq!(&"abcd"[..2], "ab");
359 assert_eq!(&"abcd"[..4], "abcd");
363 fn test_trim_left_matches() {
364 let v: &[char] = &[];
365 assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
366 let chars: &[char] = &['*', ' '];
367 assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
368 assert_eq!(" *** *** ".trim_left_matches(chars), "");
369 assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
371 assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
372 let chars: &[char] = &['1', '2'];
373 assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
374 assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
378 fn test_trim_right_matches() {
379 let v: &[char] = &[];
380 assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
381 let chars: &[char] = &['*', ' '];
382 assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
383 assert_eq!(" *** *** ".trim_right_matches(chars), "");
384 assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
386 assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
387 let chars: &[char] = &['1', '2'];
388 assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
389 assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
393 fn test_trim_matches() {
394 let v: &[char] = &[];
395 assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
396 let chars: &[char] = &['*', ' '];
397 assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
398 assert_eq!(" *** *** ".trim_matches(chars), "");
399 assert_eq!("foo".trim_matches(chars), "foo");
401 assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
402 let chars: &[char] = &['1', '2'];
403 assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
404 assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
408 fn test_trim_left() {
409 assert_eq!("".trim_left(), "");
410 assert_eq!("a".trim_left(), "a");
411 assert_eq!(" ".trim_left(), "");
412 assert_eq!(" blah".trim_left(), "blah");
413 assert_eq!(" \u{3000} wut".trim_left(), "wut");
414 assert_eq!("hey ".trim_left(), "hey ");
418 fn test_trim_right() {
419 assert_eq!("".trim_right(), "");
420 assert_eq!("a".trim_right(), "a");
421 assert_eq!(" ".trim_right(), "");
422 assert_eq!("blah ".trim_right(), "blah");
423 assert_eq!("wut \u{3000} ".trim_right(), "wut");
424 assert_eq!(" hey".trim_right(), " hey");
429 assert_eq!("".trim(), "");
430 assert_eq!("a".trim(), "a");
431 assert_eq!(" ".trim(), "");
432 assert_eq!(" blah ".trim(), "blah");
433 assert_eq!("\nwut \u{3000} ".trim(), "wut");
434 assert_eq!(" hey dude ".trim(), "hey dude");
438 fn test_is_whitespace() {
439 assert!("".chars().all(|c| c.is_whitespace()));
440 assert!(" ".chars().all(|c| c.is_whitespace()));
441 assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
442 assert!(" \n\t ".chars().all(|c| c.is_whitespace()));
443 assert!(!" _ ".chars().all(|c| c.is_whitespace()));
447 fn test_slice_shift_char() {
448 let data = "ประเทศไทย中";
449 assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
453 fn test_slice_shift_char_2() {
455 assert_eq!(empty.slice_shift_char(), None);
460 // deny overlong encodings
461 assert!(from_utf8(&[0xc0, 0x80]).is_err());
462 assert!(from_utf8(&[0xc0, 0xae]).is_err());
463 assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
464 assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
465 assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
466 assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
467 assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
470 assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
471 assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
473 assert!(from_utf8(&[0xC2, 0x80]).is_ok());
474 assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
475 assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
476 assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
477 assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
478 assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
479 assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
480 assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
484 fn from_utf8_mostly_ascii() {
485 // deny invalid bytes embedded in long stretches of ascii
487 let mut data = [0; 128];
489 assert!(from_utf8(&data).is_err());
491 assert!(from_utf8(&data).is_err());
497 use rustc_unicode::str::is_utf16;
500 ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
509 // surrogate pairs (randomly generated with Python 3's
510 // .encode('utf-16be'))
511 pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
512 &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
513 &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
515 // mixtures (also random)
516 pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
517 &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
518 &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
522 ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
526 // surrogate + regular unit
528 // surrogate + lead surrogate
530 // unterminated surrogate
532 // trail surrogate without a lead
535 // random byte sequences that Python 3's .decode('utf-16be')
537 neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
538 &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
539 &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
540 &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
541 &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
542 &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
543 &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
544 &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
545 &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
546 &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
547 &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
548 &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
549 &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
550 &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
551 &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
552 &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
553 &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
554 &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
555 &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
556 &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
557 &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
564 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
565 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
569 assert_eq!("".as_bytes(), b);
570 assert_eq!("abc".as_bytes(), b"abc");
571 assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
576 fn test_as_bytes_fail() {
577 // Don't double free. (I'm not sure if this exercises the
578 // original problem code path anymore.)
579 let s = String::from("");
580 let _bytes = s.as_bytes();
586 let buf = "hello".as_ptr();
588 assert_eq!(*buf.offset(0), b'h');
589 assert_eq!(*buf.offset(1), b'e');
590 assert_eq!(*buf.offset(2), b'l');
591 assert_eq!(*buf.offset(3), b'l');
592 assert_eq!(*buf.offset(4), b'o');
597 fn vec_str_conversions() {
598 let s1: String = String::from("All mimsy were the borogoves");
600 let v: Vec<u8> = s1.as_bytes().to_vec();
601 let s2: String = String::from(from_utf8(&v).unwrap());
607 let a: u8 = s1.as_bytes()[i];
608 let b: u8 = s2.as_bytes()[i];
618 assert!("abcde".contains("bcd"));
619 assert!("abcde".contains("abcd"));
620 assert!("abcde".contains("bcde"));
621 assert!("abcde".contains(""));
622 assert!("".contains(""));
623 assert!(!"abcde".contains("def"));
624 assert!(!"".contains("a"));
626 let data = "ประเทศไทย中华Việt Nam";
627 assert!(data.contains("ประเ"));
628 assert!(data.contains("ะเ"));
629 assert!(data.contains("中华"));
630 assert!(!data.contains("ไท华"));
634 fn test_contains_char() {
635 assert!("abc".contains('b'));
636 assert!("a".contains('a'));
637 assert!(!"abc".contains('d'));
638 assert!(!"".contains('a'));
643 let s = "ศไทย中华Việt Nam";
644 let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
647 assert!(s.char_at(pos) == *ch);
648 pos += ch.to_string().len();
653 fn test_char_at_reverse() {
654 let s = "ศไทย中华Việt Nam";
655 let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
656 let mut pos = s.len();
657 for ch in v.iter().rev() {
658 assert!(s.char_at_reverse(pos) == *ch);
659 pos -= ch.to_string().len();
665 let s = "ศไทย中华Việt Nam";
666 for (index, _) in s.char_indices() {
667 let (a, b) = s.split_at(index);
668 assert_eq!(&s[..a.len()], a);
669 assert_eq!(&s[a.len()..], b);
671 let (a, b) = s.split_at(s.len());
677 fn test_split_at_mut() {
678 use std::ascii::AsciiExt;
679 let mut s = "Hello World".to_string();
681 let (a, b) = s.split_at_mut(5);
682 a.make_ascii_uppercase();
683 b.make_ascii_lowercase();
685 assert_eq!(s, "HELLO world");
690 fn test_split_at_boundscheck() {
691 let s = "ศไทย中华Việt Nam";
696 fn test_escape_unicode() {
697 assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
698 assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
699 assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
700 assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
701 assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
702 assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
703 assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
704 assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
705 assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
709 fn test_escape_default() {
710 assert_eq!("abc".escape_default(), "abc");
711 assert_eq!("a c".escape_default(), "a c");
712 assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
713 assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
714 assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
715 assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
716 assert_eq!("ab\u{fb00}".escape_default(), "ab\\u{fb00}");
717 assert_eq!("\u{1d4ea}\r".escape_default(), "\\u{1d4ea}\\r");
721 fn test_total_ord() {
722 assert_eq!("1234".cmp("123"), Greater);
723 assert_eq!("123".cmp("1234"), Less);
724 assert_eq!("1234".cmp("1234"), Equal);
725 assert_eq!("12345555".cmp("123456"), Less);
726 assert_eq!("22".cmp("1234"), Greater);
730 fn test_char_range_at() {
731 let data = "b¢€𤭢𤭢€¢b";
732 assert_eq!('b', data.char_range_at(0).ch);
733 assert_eq!('¢', data.char_range_at(1).ch);
734 assert_eq!('€', data.char_range_at(3).ch);
735 assert_eq!('𤭢', data.char_range_at(6).ch);
736 assert_eq!('𤭢', data.char_range_at(10).ch);
737 assert_eq!('€', data.char_range_at(14).ch);
738 assert_eq!('¢', data.char_range_at(17).ch);
739 assert_eq!('b', data.char_range_at(19).ch);
743 fn test_char_range_at_reverse_underflow() {
744 assert_eq!("abc".char_range_at_reverse(0).next, 0);
749 let s = "ศไทย中华Việt Nam";
750 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
756 assert_eq!(c, v[pos]);
759 assert_eq!(pos, v.len());
763 fn test_rev_iterator() {
764 let s = "ศไทย中华Việt Nam";
765 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
768 let it = s.chars().rev();
771 assert_eq!(c, v[pos]);
774 assert_eq!(pos, v.len());
778 fn test_chars_decoding() {
779 let mut bytes = [0; 4];
780 for c in (0..0x110000).filter_map(::std::char::from_u32) {
781 let len = c.encode_utf8(&mut bytes).unwrap_or(0);
782 let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
783 if Some(c) != s.chars().next() {
784 panic!("character {:x}={} does not decode correctly", c as u32, c);
790 fn test_chars_rev_decoding() {
791 let mut bytes = [0; 4];
792 for c in (0..0x110000).filter_map(::std::char::from_u32) {
793 let len = c.encode_utf8(&mut bytes).unwrap_or(0);
794 let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
795 if Some(c) != s.chars().rev().next() {
796 panic!("character {:x}={} does not decode correctly", c as u32, c);
802 fn test_iterator_clone() {
803 let s = "ศไทย中华Việt Nam";
804 let mut it = s.chars();
806 assert!(it.clone().zip(it).all(|(x,y)| x == y));
810 fn test_bytesator() {
811 let s = "ศไทย中华Việt Nam";
813 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
814 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
820 assert_eq!(b, v[pos]);
826 fn test_bytes_revator() {
827 let s = "ศไทย中华Việt Nam";
829 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
830 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
833 let mut pos = v.len();
835 for b in s.bytes().rev() {
837 assert_eq!(b, v[pos]);
842 fn test_bytesator_nth() {
843 let s = "ศไทย中华Việt Nam";
845 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
846 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
850 let mut b = s.bytes();
851 assert_eq!(b.nth(2).unwrap(), v[2]);
852 assert_eq!(b.nth(10).unwrap(), v[10]);
853 assert_eq!(b.nth(200), None);
857 fn test_bytesator_count() {
858 let s = "ศไทย中华Việt Nam";
861 assert_eq!(b.count(), 28)
865 fn test_bytesator_last() {
866 let s = "ศไทย中华Việt Nam";
869 assert_eq!(b.last().unwrap(), 109)
873 fn test_char_indicesator() {
874 let s = "ศไทย中华Việt Nam";
875 let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
876 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
879 let it = s.char_indices();
882 assert_eq!(c, (p[pos], v[pos]));
885 assert_eq!(pos, v.len());
886 assert_eq!(pos, p.len());
890 fn test_char_indices_revator() {
891 let s = "ศไทย中华Việt Nam";
892 let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
893 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
896 let it = s.char_indices().rev();
899 assert_eq!(c, (p[pos], v[pos]));
902 assert_eq!(pos, v.len());
903 assert_eq!(pos, p.len());
907 fn test_splitn_char_iterator() {
908 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
910 let split: Vec<&str> = data.splitn(4, ' ').collect();
911 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
913 let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
914 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
917 let split: Vec<&str> = data.splitn(4, 'ä').collect();
918 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
920 let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
921 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
925 fn test_split_char_iterator_no_trailing() {
926 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
928 let split: Vec<&str> = data.split('\n').collect();
929 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
931 let split: Vec<&str> = data.split_terminator('\n').collect();
932 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
937 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
939 let split: Vec<&str> = data.rsplit(' ').collect();
940 assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
942 let split: Vec<&str> = data.rsplit("lämb").collect();
943 assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
945 let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
946 assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
951 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
953 let split: Vec<&str> = data.rsplitn(2, ' ').collect();
954 assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
956 let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
957 assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
959 let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
960 assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
964 fn test_split_whitespace() {
965 let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
966 let words: Vec<&str> = data.split_whitespace().collect();
967 assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
972 let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
973 let lines: Vec<&str> = data.lines().collect();
974 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
976 let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
977 let lines: Vec<&str> = data.lines().collect();
978 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
982 fn test_splitator() {
983 fn t(s: &str, sep: &str, u: &[&str]) {
984 let v: Vec<&str> = s.split(sep).collect();
987 t("--1233345--", "12345", &["--1233345--"]);
988 t("abc::hello::there", "::", &["abc", "hello", "there"]);
989 t("::hello::there", "::", &["", "hello", "there"]);
990 t("hello::there::", "::", &["hello", "there", ""]);
991 t("::hello::there::", "::", &["", "hello", "there", ""]);
992 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
993 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
994 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
995 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
997 t("zz", "zz", &["",""]);
998 t("ok", "z", &["ok"]);
999 t("zzz", "zz", &["","z"]);
1000 t("zzzzz", "zz", &["","","z"]);
1004 fn test_str_default() {
1005 use std::default::Default;
1007 fn t<S: Default + AsRef<str>>() {
1008 let s: S = Default::default();
1009 assert_eq!(s.as_ref(), "");
1017 fn test_str_container() {
1018 fn sum_len(v: &[&str]) -> usize {
1019 v.iter().map(|x| x.len()).sum()
1023 assert_eq!(5, sum_len(&["012", "", "34"]));
1024 assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1025 assert_eq!(5, sum_len(&[s]));
1029 fn test_str_from_utf8() {
1031 assert_eq!(from_utf8(xs), Ok("hello"));
1033 let xs = "ศไทย中华Việt Nam".as_bytes();
1034 assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1036 let xs = b"hello\xFF";
1037 assert!(from_utf8(xs).is_err());
1041 fn test_pattern_deref_forward() {
1042 let data = "aabcdaa";
1043 assert!(data.contains("bcd"));
1044 assert!(data.contains(&"bcd"));
1045 assert!(data.contains(&"bcd".to_string()));
1049 fn test_empty_match_indices() {
1051 let vec: Vec<_> = data.match_indices("").collect();
1052 assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1056 fn test_bool_from_str() {
1057 assert_eq!("true".parse().ok(), Some(true));
1058 assert_eq!("false".parse().ok(), Some(false));
1059 assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1062 fn check_contains_all_substrings(s: &str) {
1063 assert!(s.contains(""));
1064 for i in 0..s.len() {
1065 for j in i+1..s.len() + 1 {
1066 assert!(s.contains(&s[i..j]));
1072 fn strslice_issue_16589() {
1073 assert!("bananas".contains("nana"));
1075 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1076 // test all substrings for good measure
1077 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1081 fn strslice_issue_16878() {
1082 assert!(!"1234567ah012345678901ah".contains("hah"));
1083 assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1088 fn test_strslice_contains() {
1089 let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1090 check_contains_all_substrings(x);
1094 fn test_rsplitn_char_iterator() {
1095 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1097 let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1099 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1101 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1103 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1106 let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1108 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1110 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1112 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1116 fn test_split_char_iterator() {
1117 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1119 let split: Vec<&str> = data.split(' ').collect();
1120 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1122 let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1124 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1126 let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1127 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1129 let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1131 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1134 let split: Vec<&str> = data.split('ä').collect();
1135 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1137 let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1139 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1141 let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1142 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1144 let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1146 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1150 fn test_rev_split_char_iterator_no_trailing() {
1151 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1153 let mut split: Vec<&str> = data.split('\n').rev().collect();
1155 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1157 let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1159 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1163 fn test_utf16_code_units() {
1164 use rustc_unicode::str::Utf16Encoder;
1165 assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1166 [0xE9, 0xD83D, 0xDCA9])
1170 fn starts_with_in_unicode() {
1171 assert!(!"├── Cargo.toml".starts_with("# "));
1175 fn starts_short_long() {
1176 assert!(!"".starts_with("##"));
1177 assert!(!"##".starts_with("####"));
1178 assert!("####".starts_with("##"));
1179 assert!(!"##ä".starts_with("####"));
1180 assert!("####ä".starts_with("##"));
1181 assert!(!"##".starts_with("####ä"));
1182 assert!("##ä##".starts_with("##ä"));
1184 assert!("".starts_with(""));
1185 assert!("ä".starts_with(""));
1186 assert!("#ä".starts_with(""));
1187 assert!("##ä".starts_with(""));
1188 assert!("ä###".starts_with(""));
1189 assert!("#ä##".starts_with(""));
1190 assert!("##ä#".starts_with(""));
1194 fn contains_weird_cases() {
1195 assert!("* \t".contains(' '));
1196 assert!(!"* \t".contains('?'));
1197 assert!(!"* \t".contains('\u{1F4A9}'));
1202 assert_eq!(" \t a \t ".trim_left_matches(|c: char| c.is_whitespace()),
1204 assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()),
1206 assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()),
1208 assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()),
1210 assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()),
1212 assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()),
1218 assert_eq!("".to_lowercase(), "");
1219 assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1221 // https://github.com/rust-lang/rust/issues/26035
1222 assert_eq!("ΑΣ".to_lowercase(), "ας");
1223 assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1224 assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1226 assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1227 assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1228 assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1230 assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1231 assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1233 assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1234 assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1236 assert_eq!("Α Σ".to_lowercase(), "α σ");
1237 assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1238 assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1240 assert_eq!("Σ".to_lowercase(), "σ");
1241 assert_eq!("'Σ".to_lowercase(), "'σ");
1242 assert_eq!("''Σ".to_lowercase(), "''σ");
1244 assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1245 assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1246 assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1251 assert_eq!("".to_uppercase(), "");
1252 assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1256 fn test_into_string() {
1257 // The only way to acquire a Box<str> in the first place is through a String, so just
1258 // test that we can round-trip between Box<str> and String.
1259 let string = String::from("Some text goes here");
1260 assert_eq!(string.clone().into_boxed_str().into_string(), string);
1264 fn test_box_slice_clone() {
1265 let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1266 let data2 = data.clone().into_boxed_str().clone().into_string();
1268 assert_eq!(data, data2);
1272 fn test_cow_from() {
1273 let borrowed = "borrowed";
1274 let owned = String::from("owned");
1275 match (Cow::from(owned.clone()), Cow::from(borrowed)) {
1276 (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
1277 _ => panic!("invalid `Cow::from`"),
1282 use std::str::pattern::Pattern;
1283 use std::str::pattern::{Searcher, ReverseSearcher};
1284 use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1286 macro_rules! make_test {
1287 ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1288 #[allow(unused_imports)]
1290 use std::str::pattern::SearchStep::{Match, Reject};
1291 use super::{cmp_search_to_vec};
1294 cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1298 cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1304 fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1305 right: Vec<SearchStep>)
1306 where P::Searcher: ReverseSearcher<'a>
1308 let mut searcher = pat.into_searcher(haystack);
1311 match if !rev {searcher.next()} else {searcher.next_back()} {
1312 Match(a, b) => v.push(Match(a, b)),
1313 Reject(a, b) => v.push(Reject(a, b)),
1321 let mut first_index = 0;
1324 for (i, e) in right.iter().enumerate() {
1326 Match(a, b) | Reject(a, b)
1327 if a <= b && a == first_index => {
1337 if let Some(err) = err {
1338 panic!("Input skipped range at {}", err);
1341 if first_index != haystack.len() {
1342 panic!("Did not cover whole input");
1345 assert_eq!(v, right);
1348 make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1355 make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1363 make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1380 make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1385 make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1394 make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1397 make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1399 make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1408 make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1413 make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1421 macro_rules! generate_iterator_test {
1425 ($($arg:expr),*) -> [$($t:tt)*];
1428 with $fwd:expr, $bwd:expr;
1434 let res = vec![$($t)*];
1436 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1437 assert_eq!(fwd_vec, res);
1439 let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1441 assert_eq!(bwd_vec, res);
1449 ($($arg:expr),*) -> [$($t:tt)*];
1458 let res = vec![$($t)*];
1460 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1461 assert_eq!(fwd_vec, res);
1468 generate_iterator_test! {
1469 double_ended_split {
1470 ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1471 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1473 with str::split, str::rsplit;
1476 generate_iterator_test! {
1477 double_ended_split_terminator {
1478 ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1480 with str::split_terminator, str::rsplit_terminator;
1483 generate_iterator_test! {
1484 double_ended_matches {
1485 ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1487 with str::matches, str::rmatches;
1490 generate_iterator_test! {
1491 double_ended_match_indices {
1492 ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1494 with str::match_indices, str::rmatch_indices;
1497 generate_iterator_test! {
1498 not_double_ended_splitn {
1499 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1504 generate_iterator_test! {
1505 not_double_ended_rsplitn {
1506 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1512 use test::{Bencher, black_box};
1515 fn char_iterator(b: &mut Bencher) {
1516 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1518 b.iter(|| s.chars().count());
1522 fn char_iterator_for(b: &mut Bencher) {
1523 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1526 for ch in s.chars() { black_box(ch); }
1531 fn char_iterator_ascii(b: &mut Bencher) {
1532 let s = "Mary had a little lamb, Little lamb
1533 Mary had a little lamb, Little lamb
1534 Mary had a little lamb, Little lamb
1535 Mary had a little lamb, Little lamb
1536 Mary had a little lamb, Little lamb
1537 Mary had a little lamb, Little lamb";
1539 b.iter(|| s.chars().count());
1543 fn char_iterator_rev(b: &mut Bencher) {
1544 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1546 b.iter(|| s.chars().rev().count());
1550 fn char_iterator_rev_for(b: &mut Bencher) {
1551 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1554 for ch in s.chars().rev() { black_box(ch); }
1559 fn char_indicesator(b: &mut Bencher) {
1560 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1561 let len = s.chars().count();
1563 b.iter(|| assert_eq!(s.char_indices().count(), len));
1567 fn char_indicesator_rev(b: &mut Bencher) {
1568 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1569 let len = s.chars().count();
1571 b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
1575 fn split_unicode_ascii(b: &mut Bencher) {
1576 let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
1578 b.iter(|| assert_eq!(s.split('V').count(), 3));
1582 fn split_ascii(b: &mut Bencher) {
1583 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1584 let len = s.split(' ').count();
1586 b.iter(|| assert_eq!(s.split(' ').count(), len));
1590 fn split_extern_fn(b: &mut Bencher) {
1591 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1592 let len = s.split(' ').count();
1593 fn pred(c: char) -> bool { c == ' ' }
1595 b.iter(|| assert_eq!(s.split(pred).count(), len));
1599 fn split_closure(b: &mut Bencher) {
1600 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1601 let len = s.split(' ').count();
1603 b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
1607 fn split_slice(b: &mut Bencher) {
1608 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1609 let len = s.split(' ').count();
1611 let c: &[char] = &[' '];
1612 b.iter(|| assert_eq!(s.split(c).count(), len));
1616 fn bench_join(b: &mut Bencher) {
1617 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1619 let v = vec![s, s, s, s, s, s, s, s, s, s];
1621 assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9);
1626 fn bench_contains_short_short(b: &mut Bencher) {
1627 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1631 assert!(haystack.contains(needle));
1636 fn bench_contains_short_long(b: &mut Bencher) {
1638 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1639 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1640 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1641 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1642 tempus vel, gravida nec quam.
1644 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1645 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1646 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1647 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1648 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1649 interdum. Curabitur ut nisi justo.
1651 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1652 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1653 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1654 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1655 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1656 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1657 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1658 Aliquam sit amet placerat lorem.
1660 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1661 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1662 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1663 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1664 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1667 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1668 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1669 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1670 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1671 malesuada sollicitudin quam eu fermentum.";
1672 let needle = "english";
1675 assert!(!haystack.contains(needle));
1680 fn bench_contains_bad_naive(b: &mut Bencher) {
1681 let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1682 let needle = "aaaaaaaab";
1685 assert!(!haystack.contains(needle));
1690 fn bench_contains_equal(b: &mut Bencher) {
1691 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1692 let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1695 assert!(haystack.contains(needle));
1699 macro_rules! make_test_inner {
1700 ($s:ident, $code:expr, $name:ident, $str:expr) => {
1702 fn $name(bencher: &mut Bencher) {
1705 bencher.iter(|| $code);
1710 macro_rules! make_test {
1711 ($name:ident, $s:ident, $code:expr) => {
1714 use test::black_box;
1716 // Short strings: 65 bytes each
1717 make_test_inner!($s, $code, short_ascii,
1718 "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
1719 make_test_inner!($s, $code, short_mixed,
1720 "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
1721 make_test_inner!($s, $code, short_pile_of_poo,
1722 "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
1723 make_test_inner!($s, $code, long_lorem_ipsum,"\
1724 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1725 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1726 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1727 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1728 tempus vel, gravida nec quam.
1730 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1731 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1732 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1733 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1734 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1735 interdum. Curabitur ut nisi justo.
1737 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1738 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1739 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1740 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1741 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1742 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1743 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1744 Aliquam sit amet placerat lorem.
1746 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1747 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1748 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1749 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1750 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1753 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1754 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1755 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1756 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1757 malesuada sollicitudin quam eu fermentum!");
1762 make_test!(chars_count, s, s.chars().count());
1764 make_test!(contains_bang_str, s, s.contains("!"));
1765 make_test!(contains_bang_char, s, s.contains('!'));
1767 make_test!(match_indices_a_str, s, s.match_indices("a").count());
1769 make_test!(split_a_str, s, s.split("a").count());
1771 make_test!(trim_ascii_char, s, {
1772 use std::ascii::AsciiExt;
1773 s.trim_matches(|c: char| c.is_ascii())
1775 make_test!(trim_left_ascii_char, s, {
1776 use std::ascii::AsciiExt;
1777 s.trim_left_matches(|c: char| c.is_ascii())
1779 make_test!(trim_right_ascii_char, s, {
1780 use std::ascii::AsciiExt;
1781 s.trim_right_matches(|c: char| c.is_ascii())
1784 make_test!(find_underscore_char, s, s.find('_'));
1785 make_test!(rfind_underscore_char, s, s.rfind('_'));
1786 make_test!(find_underscore_str, s, s.find("_"));
1788 make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
1789 make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
1790 make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
1792 make_test!(split_space_char, s, s.split(' ').count());
1793 make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
1795 make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
1796 make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
1798 make_test!(split_space_str, s, s.split(" ").count());
1799 make_test!(split_ad_str, s, s.split("ad").count());