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.
11 use std::cmp::Ordering::{Equal, Greater, Less};
12 use std::str::from_utf8;
18 assert!("foo" <= "foo");
19 assert!("foo" != "bar");
24 assert_eq!("hello".find('l'), Some(2));
25 assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
26 assert!("hello".find('x').is_none());
27 assert!("hello".find(|c:char| c == 'x').is_none());
28 assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
29 assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
34 assert_eq!("hello".rfind('l'), Some(3));
35 assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
36 assert!("hello".rfind('x').is_none());
37 assert!("hello".rfind(|c:char| c == 'x').is_none());
38 assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
39 assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
45 let s: String = empty.chars().collect();
47 let data = "ประเทศไทย中";
48 let s: String = data.chars().collect();
53 fn test_into_bytes() {
54 let data = String::from("asdf");
55 let buf = data.into_bytes();
56 assert_eq!(buf, b"asdf");
62 assert_eq!("".find(""), Some(0));
63 assert!("banana".find("apple pie").is_none());
66 assert_eq!(data[0..6].find("ab"), Some(0));
67 assert_eq!(data[2..6].find("ab"), Some(3 - 2));
68 assert!(data[2..4].find("ab").is_none());
70 let string = "ประเทศไทย中华Việt Nam";
71 let mut data = String::from(string);
72 data.push_str(string);
73 assert!(data.find("ไท华").is_none());
74 assert_eq!(data[0..43].find(""), Some(0));
75 assert_eq!(data[6..43].find(""), Some(6 - 6));
77 assert_eq!(data[0..43].find("ประ"), Some( 0));
78 assert_eq!(data[0..43].find("ทศไ"), Some(12));
79 assert_eq!(data[0..43].find("ย中"), Some(24));
80 assert_eq!(data[0..43].find("iệt"), Some(34));
81 assert_eq!(data[0..43].find("Nam"), Some(40));
83 assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
84 assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
85 assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
86 assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
87 assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
89 // find every substring -- assert that it finds it, or an earlier occurrence.
90 let string = "Việt Namacbaabcaabaaba";
91 for (i, ci) in string.char_indices() {
92 let ip = i + ci.len_utf8();
93 for j in string[ip..].char_indices()
95 .chain(Some(string.len() - ip))
97 let pat = &string[i..ip + j];
98 assert!(match string.find(pat) {
102 assert!(match string.rfind(pat) {
110 fn s(x: &str) -> String { x.to_string() }
112 macro_rules! test_concat {
113 ($expected: expr, $string: expr) => {
115 let s: String = $string.concat();
116 assert_eq!($expected, s);
122 fn test_concat_for_different_types() {
123 test_concat!("ab", vec![s("a"), s("b")]);
124 test_concat!("ab", vec!["a", "b"]);
125 test_concat!("ab", vec!["a", "b"]);
126 test_concat!("ab", vec![s("a"), s("b")]);
130 fn test_concat_for_different_lengths() {
131 let empty: &[&str] = &[];
132 test_concat!("", empty);
133 test_concat!("a", ["a"]);
134 test_concat!("ab", ["a", "b"]);
135 test_concat!("abc", ["", "a", "bc"]);
138 macro_rules! test_join {
139 ($expected: expr, $string: expr, $delim: expr) => {
141 let s = $string.join($delim);
142 assert_eq!($expected, s);
148 fn test_join_for_different_types() {
149 test_join!("a-b", ["a", "b"], "-");
150 let hyphen = "-".to_string();
151 test_join!("a-b", [s("a"), s("b")], &*hyphen);
152 test_join!("a-b", vec!["a", "b"], &*hyphen);
153 test_join!("a-b", &*vec!["a", "b"], "-");
154 test_join!("a-b", vec![s("a"), s("b")], "-");
158 fn test_join_for_different_lengths() {
159 let empty: &[&str] = &[];
160 test_join!("", empty, "-");
161 test_join!("a", ["a"], "-");
162 test_join!("a-b", ["a", "b"], "-");
163 test_join!("-a-bc", ["", "a", "bc"], "-");
167 fn test_unsafe_slice() {
168 assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
169 assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
170 assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
171 fn a_million_letter_a() -> String {
173 let mut rs = String::new();
175 rs.push_str("aaaaaaaaaa");
180 fn half_a_million_letter_a() -> String {
182 let mut rs = String::new();
184 rs.push_str("aaaaa");
189 let letters = a_million_letter_a();
190 assert_eq!(half_a_million_letter_a(),
191 unsafe { letters.slice_unchecked(0, 500000)});
195 fn test_starts_with() {
196 assert!(("".starts_with("")));
197 assert!(("abc".starts_with("")));
198 assert!(("abc".starts_with("a")));
199 assert!((!"a".starts_with("abc")));
200 assert!((!"".starts_with("abc")));
201 assert!((!"ödd".starts_with("-")));
202 assert!(("ödd".starts_with("öd")));
206 fn test_ends_with() {
207 assert!(("".ends_with("")));
208 assert!(("abc".ends_with("")));
209 assert!(("abc".ends_with("c")));
210 assert!((!"a".ends_with("abc")));
211 assert!((!"".ends_with("abc")));
212 assert!((!"ddö".ends_with("-")));
213 assert!(("ddö".ends_with("dö")));
218 assert!("".is_empty());
219 assert!(!"a".is_empty());
225 assert_eq!("".replace(a, "b"), "");
226 assert_eq!("a".replace(a, "b"), "b");
227 assert_eq!("ab".replace(a, "b"), "bb");
229 assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
230 assert_eq!(" test test ".replace(test, ""), " ");
234 fn test_replace_2a() {
235 let data = "ประเทศไทย中华";
236 let repl = "دولة الكويت";
239 let a2 = "دولة الكويتทศไทย中华";
240 assert_eq!(data.replace(a, repl), a2);
244 fn test_replace_2b() {
245 let data = "ประเทศไทย中华";
246 let repl = "دولة الكويت";
249 let b2 = "ปรدولة الكويتทศไทย中华";
250 assert_eq!(data.replace(b, repl), b2);
254 fn test_replace_2c() {
255 let data = "ประเทศไทย中华";
256 let repl = "دولة الكويت";
259 let c2 = "ประเทศไทยدولة الكويت";
260 assert_eq!(data.replace(c, repl), c2);
264 fn test_replace_2d() {
265 let data = "ประเทศไทย中华";
266 let repl = "دولة الكويت";
269 assert_eq!(data.replace(d, repl), data);
273 fn test_replace_pattern() {
274 let data = "abcdαβγδabcdαβγδ";
275 assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
276 assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
277 assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
278 assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
283 assert_eq!("ab", &"abc"[0..2]);
284 assert_eq!("bc", &"abc"[1..3]);
285 assert_eq!("", &"abc"[1..1]);
286 assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
288 let data = "ประเทศไทย中华";
289 assert_eq!("ป", &data[0..3]);
290 assert_eq!("ร", &data[3..6]);
291 assert_eq!("", &data[3..3]);
292 assert_eq!("华", &data[30..33]);
294 fn a_million_letter_x() -> String {
296 let mut rs = String::new();
298 rs.push_str("华华华华华华华华华华");
303 fn half_a_million_letter_x() -> String {
305 let mut rs = String::new();
307 rs.push_str("华华华华华");
312 let letters = a_million_letter_x();
313 assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
318 let ss = "中华Việt Nam";
320 assert_eq!("华", &ss[3..6]);
321 assert_eq!("Việt Nam", &ss[6..16]);
323 assert_eq!("ab", &"abc"[0..2]);
324 assert_eq!("bc", &"abc"[1..3]);
325 assert_eq!("", &"abc"[1..1]);
327 assert_eq!("中", &ss[0..3]);
328 assert_eq!("华V", &ss[3..7]);
329 assert_eq!("", &ss[3..3]);
344 fn test_slice_fail() {
349 fn test_slice_from() {
350 assert_eq!(&"abcd"[0..], "abcd");
351 assert_eq!(&"abcd"[2..], "cd");
352 assert_eq!(&"abcd"[4..], "");
356 assert_eq!(&"abcd"[..0], "");
357 assert_eq!(&"abcd"[..2], "ab");
358 assert_eq!(&"abcd"[..4], "abcd");
362 fn test_trim_left_matches() {
363 let v: &[char] = &[];
364 assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
365 let chars: &[char] = &['*', ' '];
366 assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
367 assert_eq!(" *** *** ".trim_left_matches(chars), "");
368 assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
370 assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
371 let chars: &[char] = &['1', '2'];
372 assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
373 assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
377 fn test_trim_right_matches() {
378 let v: &[char] = &[];
379 assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
380 let chars: &[char] = &['*', ' '];
381 assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
382 assert_eq!(" *** *** ".trim_right_matches(chars), "");
383 assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
385 assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
386 let chars: &[char] = &['1', '2'];
387 assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
388 assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
392 fn test_trim_matches() {
393 let v: &[char] = &[];
394 assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
395 let chars: &[char] = &['*', ' '];
396 assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
397 assert_eq!(" *** *** ".trim_matches(chars), "");
398 assert_eq!("foo".trim_matches(chars), "foo");
400 assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
401 let chars: &[char] = &['1', '2'];
402 assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
403 assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
407 fn test_trim_left() {
408 assert_eq!("".trim_left(), "");
409 assert_eq!("a".trim_left(), "a");
410 assert_eq!(" ".trim_left(), "");
411 assert_eq!(" blah".trim_left(), "blah");
412 assert_eq!(" \u{3000} wut".trim_left(), "wut");
413 assert_eq!("hey ".trim_left(), "hey ");
417 fn test_trim_right() {
418 assert_eq!("".trim_right(), "");
419 assert_eq!("a".trim_right(), "a");
420 assert_eq!(" ".trim_right(), "");
421 assert_eq!("blah ".trim_right(), "blah");
422 assert_eq!("wut \u{3000} ".trim_right(), "wut");
423 assert_eq!(" hey".trim_right(), " hey");
428 assert_eq!("".trim(), "");
429 assert_eq!("a".trim(), "a");
430 assert_eq!(" ".trim(), "");
431 assert_eq!(" blah ".trim(), "blah");
432 assert_eq!("\nwut \u{3000} ".trim(), "wut");
433 assert_eq!(" hey dude ".trim(), "hey dude");
437 fn test_is_whitespace() {
438 assert!("".chars().all(|c| c.is_whitespace()));
439 assert!(" ".chars().all(|c| c.is_whitespace()));
440 assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
441 assert!(" \n\t ".chars().all(|c| c.is_whitespace()));
442 assert!(!" _ ".chars().all(|c| c.is_whitespace()));
446 fn test_slice_shift_char() {
447 let data = "ประเทศไทย中";
448 assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
452 fn test_slice_shift_char_2() {
454 assert_eq!(empty.slice_shift_char(), None);
459 // deny overlong encodings
460 assert!(from_utf8(&[0xc0, 0x80]).is_err());
461 assert!(from_utf8(&[0xc0, 0xae]).is_err());
462 assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
463 assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
464 assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
465 assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
466 assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
469 assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
470 assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
472 assert!(from_utf8(&[0xC2, 0x80]).is_ok());
473 assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
474 assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
475 assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
476 assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
477 assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
478 assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
479 assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
483 fn from_utf8_mostly_ascii() {
484 // deny invalid bytes embedded in long stretches of ascii
486 let mut data = [0; 128];
488 assert!(from_utf8(&data).is_err());
490 assert!(from_utf8(&data).is_err());
496 use rustc_unicode::str::is_utf16;
499 ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
508 // surrogate pairs (randomly generated with Python 3's
509 // .encode('utf-16be'))
510 pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
511 &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
512 &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
514 // mixtures (also random)
515 pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
516 &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
517 &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
521 ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
525 // surrogate + regular unit
527 // surrogate + lead surrogate
529 // unterminated surrogate
531 // trail surrogate without a lead
534 // random byte sequences that Python 3's .decode('utf-16be')
536 neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
537 &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
538 &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
539 &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
540 &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
541 &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
542 &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
543 &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
544 &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
545 &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
546 &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
547 &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
548 &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
549 &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
550 &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
551 &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
552 &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
553 &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
554 &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
555 &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
556 &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
563 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
564 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
568 assert_eq!("".as_bytes(), b);
569 assert_eq!("abc".as_bytes(), b"abc");
570 assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
575 fn test_as_bytes_fail() {
576 // Don't double free. (I'm not sure if this exercises the
577 // original problem code path anymore.)
578 let s = String::from("");
579 let _bytes = s.as_bytes();
585 let buf = "hello".as_ptr();
587 assert_eq!(*buf.offset(0), b'h');
588 assert_eq!(*buf.offset(1), b'e');
589 assert_eq!(*buf.offset(2), b'l');
590 assert_eq!(*buf.offset(3), b'l');
591 assert_eq!(*buf.offset(4), b'o');
596 fn vec_str_conversions() {
597 let s1: String = String::from("All mimsy were the borogoves");
599 let v: Vec<u8> = s1.as_bytes().to_vec();
600 let s2: String = String::from(from_utf8(&v).unwrap());
606 let a: u8 = s1.as_bytes()[i];
607 let b: u8 = s2.as_bytes()[i];
617 assert!("abcde".contains("bcd"));
618 assert!("abcde".contains("abcd"));
619 assert!("abcde".contains("bcde"));
620 assert!("abcde".contains(""));
621 assert!("".contains(""));
622 assert!(!"abcde".contains("def"));
623 assert!(!"".contains("a"));
625 let data = "ประเทศไทย中华Việt Nam";
626 assert!(data.contains("ประเ"));
627 assert!(data.contains("ะเ"));
628 assert!(data.contains("中华"));
629 assert!(!data.contains("ไท华"));
633 fn test_contains_char() {
634 assert!("abc".contains('b'));
635 assert!("a".contains('a'));
636 assert!(!"abc".contains('d'));
637 assert!(!"".contains('a'));
642 let s = "ศไทย中华Việt Nam";
643 let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
646 assert!(s.char_at(pos) == *ch);
647 pos += ch.to_string().len();
652 fn test_char_at_reverse() {
653 let s = "ศไทย中华Việt Nam";
654 let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
655 let mut pos = s.len();
656 for ch in v.iter().rev() {
657 assert!(s.char_at_reverse(pos) == *ch);
658 pos -= ch.to_string().len();
664 let s = "ศไทย中华Việt Nam";
665 for (index, _) in s.char_indices() {
666 let (a, b) = s.split_at(index);
667 assert_eq!(&s[..a.len()], a);
668 assert_eq!(&s[a.len()..], b);
670 let (a, b) = s.split_at(s.len());
676 fn test_split_at_mut() {
677 use std::ascii::AsciiExt;
678 let mut s = "Hello World".to_string();
680 let (a, b) = s.split_at_mut(5);
681 a.make_ascii_uppercase();
682 b.make_ascii_lowercase();
684 assert_eq!(s, "HELLO world");
689 fn test_split_at_boundscheck() {
690 let s = "ศไทย中华Việt Nam";
695 fn test_escape_unicode() {
696 assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
697 assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
698 assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
699 assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
700 assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
701 assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
702 assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
703 assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
704 assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
708 fn test_escape_default() {
709 assert_eq!("abc".escape_default(), "abc");
710 assert_eq!("a c".escape_default(), "a c");
711 assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
712 assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
713 assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
714 assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
715 assert_eq!("ab\u{fb00}".escape_default(), "ab\\u{fb00}");
716 assert_eq!("\u{1d4ea}\r".escape_default(), "\\u{1d4ea}\\r");
720 fn test_total_ord() {
721 assert_eq!("1234".cmp("123"), Greater);
722 assert_eq!("123".cmp("1234"), Less);
723 assert_eq!("1234".cmp("1234"), Equal);
724 assert_eq!("12345555".cmp("123456"), Less);
725 assert_eq!("22".cmp("1234"), Greater);
729 fn test_char_range_at() {
730 let data = "b¢€𤭢𤭢€¢b";
731 assert_eq!('b', data.char_range_at(0).ch);
732 assert_eq!('¢', data.char_range_at(1).ch);
733 assert_eq!('€', data.char_range_at(3).ch);
734 assert_eq!('𤭢', data.char_range_at(6).ch);
735 assert_eq!('𤭢', data.char_range_at(10).ch);
736 assert_eq!('€', data.char_range_at(14).ch);
737 assert_eq!('¢', data.char_range_at(17).ch);
738 assert_eq!('b', data.char_range_at(19).ch);
742 fn test_char_range_at_reverse_underflow() {
743 assert_eq!("abc".char_range_at_reverse(0).next, 0);
748 let s = "ศไทย中华Việt Nam";
749 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
755 assert_eq!(c, v[pos]);
758 assert_eq!(pos, v.len());
762 fn test_rev_iterator() {
763 let s = "ศไทย中华Việt Nam";
764 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
767 let it = s.chars().rev();
770 assert_eq!(c, v[pos]);
773 assert_eq!(pos, v.len());
777 fn test_chars_decoding() {
778 let mut bytes = [0; 4];
779 for c in (0..0x110000).filter_map(::std::char::from_u32) {
780 let len = c.encode_utf8(&mut bytes).unwrap_or(0);
781 let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
782 if Some(c) != s.chars().next() {
783 panic!("character {:x}={} does not decode correctly", c as u32, c);
789 fn test_chars_rev_decoding() {
790 let mut bytes = [0; 4];
791 for c in (0..0x110000).filter_map(::std::char::from_u32) {
792 let len = c.encode_utf8(&mut bytes).unwrap_or(0);
793 let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
794 if Some(c) != s.chars().rev().next() {
795 panic!("character {:x}={} does not decode correctly", c as u32, c);
801 fn test_iterator_clone() {
802 let s = "ศไทย中华Việt Nam";
803 let mut it = s.chars();
805 assert!(it.clone().zip(it).all(|(x,y)| x == y));
809 fn test_bytesator() {
810 let s = "ศไทย中华Việt Nam";
812 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
813 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
819 assert_eq!(b, v[pos]);
825 fn test_bytes_revator() {
826 let s = "ศไทย中华Việt Nam";
828 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
829 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
832 let mut pos = v.len();
834 for b in s.bytes().rev() {
836 assert_eq!(b, v[pos]);
841 fn test_bytesator_nth() {
842 let s = "ศไทย中华Việt Nam";
844 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
845 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
849 let mut b = s.bytes();
850 assert_eq!(b.nth(2).unwrap(), v[2]);
851 assert_eq!(b.nth(10).unwrap(), v[10]);
852 assert_eq!(b.nth(200), None);
856 fn test_bytesator_count() {
857 let s = "ศไทย中华Việt Nam";
860 assert_eq!(b.count(), 28)
864 fn test_bytesator_last() {
865 let s = "ศไทย中华Việt Nam";
868 assert_eq!(b.last().unwrap(), 109)
872 fn test_char_indicesator() {
873 let s = "ศไทย中华Việt Nam";
874 let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
875 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
878 let it = s.char_indices();
881 assert_eq!(c, (p[pos], v[pos]));
884 assert_eq!(pos, v.len());
885 assert_eq!(pos, p.len());
889 fn test_char_indices_revator() {
890 let s = "ศไทย中华Việt Nam";
891 let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
892 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
895 let it = s.char_indices().rev();
898 assert_eq!(c, (p[pos], v[pos]));
901 assert_eq!(pos, v.len());
902 assert_eq!(pos, p.len());
906 fn test_splitn_char_iterator() {
907 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
909 let split: Vec<&str> = data.splitn(4, ' ').collect();
910 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
912 let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
913 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
916 let split: Vec<&str> = data.splitn(4, 'ä').collect();
917 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
919 let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
920 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
924 fn test_split_char_iterator_no_trailing() {
925 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
927 let split: Vec<&str> = data.split('\n').collect();
928 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
930 let split: Vec<&str> = data.split_terminator('\n').collect();
931 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
936 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
938 let split: Vec<&str> = data.rsplit(' ').collect();
939 assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
941 let split: Vec<&str> = data.rsplit("lämb").collect();
942 assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
944 let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
945 assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
950 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
952 let split: Vec<&str> = data.rsplitn(2, ' ').collect();
953 assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
955 let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
956 assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
958 let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
959 assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
963 fn test_split_whitespace() {
964 let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
965 let words: Vec<&str> = data.split_whitespace().collect();
966 assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
971 let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
972 let lines: Vec<&str> = data.lines().collect();
973 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
975 let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
976 let lines: Vec<&str> = data.lines().collect();
977 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
981 fn test_splitator() {
982 fn t(s: &str, sep: &str, u: &[&str]) {
983 let v: Vec<&str> = s.split(sep).collect();
986 t("--1233345--", "12345", &["--1233345--"]);
987 t("abc::hello::there", "::", &["abc", "hello", "there"]);
988 t("::hello::there", "::", &["", "hello", "there"]);
989 t("hello::there::", "::", &["hello", "there", ""]);
990 t("::hello::there::", "::", &["", "hello", "there", ""]);
991 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
992 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
993 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
994 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
996 t("zz", "zz", &["",""]);
997 t("ok", "z", &["ok"]);
998 t("zzz", "zz", &["","z"]);
999 t("zzzzz", "zz", &["","","z"]);
1003 fn test_str_default() {
1004 use std::default::Default;
1006 fn t<S: Default + AsRef<str>>() {
1007 let s: S = Default::default();
1008 assert_eq!(s.as_ref(), "");
1016 fn test_str_container() {
1017 fn sum_len(v: &[&str]) -> usize {
1018 v.iter().map(|x| x.len()).sum()
1022 assert_eq!(5, sum_len(&["012", "", "34"]));
1023 assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1024 assert_eq!(5, sum_len(&[s]));
1028 fn test_str_from_utf8() {
1030 assert_eq!(from_utf8(xs), Ok("hello"));
1032 let xs = "ศไทย中华Việt Nam".as_bytes();
1033 assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1035 let xs = b"hello\xFF";
1036 assert!(from_utf8(xs).is_err());
1040 fn test_pattern_deref_forward() {
1041 let data = "aabcdaa";
1042 assert!(data.contains("bcd"));
1043 assert!(data.contains(&"bcd"));
1044 assert!(data.contains(&"bcd".to_string()));
1048 fn test_empty_match_indices() {
1050 let vec: Vec<_> = data.match_indices("").collect();
1051 assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1055 fn test_bool_from_str() {
1056 assert_eq!("true".parse().ok(), Some(true));
1057 assert_eq!("false".parse().ok(), Some(false));
1058 assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1061 fn check_contains_all_substrings(s: &str) {
1062 assert!(s.contains(""));
1063 for i in 0..s.len() {
1064 for j in i+1..s.len() + 1 {
1065 assert!(s.contains(&s[i..j]));
1071 fn strslice_issue_16589() {
1072 assert!("bananas".contains("nana"));
1074 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1075 // test all substrings for good measure
1076 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1080 fn strslice_issue_16878() {
1081 assert!(!"1234567ah012345678901ah".contains("hah"));
1082 assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1087 fn test_strslice_contains() {
1088 let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1089 check_contains_all_substrings(x);
1093 fn test_rsplitn_char_iterator() {
1094 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1096 let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1098 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1100 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1102 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1105 let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1107 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1109 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1111 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1115 fn test_split_char_iterator() {
1116 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1118 let split: Vec<&str> = data.split(' ').collect();
1119 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1121 let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1123 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1125 let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1126 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1128 let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1130 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1133 let split: Vec<&str> = data.split('ä').collect();
1134 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1136 let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1138 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1140 let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1141 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1143 let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1145 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1149 fn test_rev_split_char_iterator_no_trailing() {
1150 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1152 let mut split: Vec<&str> = data.split('\n').rev().collect();
1154 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1156 let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1158 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1162 fn test_utf16_code_units() {
1163 use rustc_unicode::str::Utf16Encoder;
1164 assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1165 [0xE9, 0xD83D, 0xDCA9])
1169 fn starts_with_in_unicode() {
1170 assert!(!"├── Cargo.toml".starts_with("# "));
1174 fn starts_short_long() {
1175 assert!(!"".starts_with("##"));
1176 assert!(!"##".starts_with("####"));
1177 assert!("####".starts_with("##"));
1178 assert!(!"##ä".starts_with("####"));
1179 assert!("####ä".starts_with("##"));
1180 assert!(!"##".starts_with("####ä"));
1181 assert!("##ä##".starts_with("##ä"));
1183 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(""));
1193 fn contains_weird_cases() {
1194 assert!("* \t".contains(' '));
1195 assert!(!"* \t".contains('?'));
1196 assert!(!"* \t".contains('\u{1F4A9}'));
1201 assert_eq!(" \t a \t ".trim_left_matches(|c: char| c.is_whitespace()),
1203 assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()),
1205 assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()),
1207 assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()),
1209 assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()),
1211 assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()),
1217 assert_eq!("".to_lowercase(), "");
1218 assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1220 // https://github.com/rust-lang/rust/issues/26035
1221 assert_eq!("ΑΣ".to_lowercase(), "ας");
1222 assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1223 assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1225 assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1226 assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1227 assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1229 assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1230 assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1232 assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1233 assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1235 assert_eq!("Α Σ".to_lowercase(), "α σ");
1236 assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1237 assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1239 assert_eq!("Σ".to_lowercase(), "σ");
1240 assert_eq!("'Σ".to_lowercase(), "'σ");
1241 assert_eq!("''Σ".to_lowercase(), "''σ");
1243 assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1244 assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1245 assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1250 assert_eq!("".to_uppercase(), "");
1251 assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1255 fn test_into_string() {
1256 // The only way to acquire a Box<str> in the first place is through a String, so just
1257 // test that we can round-trip between Box<str> and String.
1258 let string = String::from("Some text goes here");
1259 assert_eq!(string.clone().into_boxed_str().into_string(), string);
1263 fn test_box_slice_clone() {
1264 let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1265 let data2 = data.clone().into_boxed_str().clone().into_string();
1267 assert_eq!(data, data2);
1271 use std::str::pattern::Pattern;
1272 use std::str::pattern::{Searcher, ReverseSearcher};
1273 use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1275 macro_rules! make_test {
1276 ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1277 #[allow(unused_imports)]
1279 use std::str::pattern::SearchStep::{Match, Reject};
1280 use super::{cmp_search_to_vec};
1283 cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1287 cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1293 fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1294 right: Vec<SearchStep>)
1295 where P::Searcher: ReverseSearcher<'a>
1297 let mut searcher = pat.into_searcher(haystack);
1300 match if !rev {searcher.next()} else {searcher.next_back()} {
1301 Match(a, b) => v.push(Match(a, b)),
1302 Reject(a, b) => v.push(Reject(a, b)),
1310 let mut first_index = 0;
1313 for (i, e) in right.iter().enumerate() {
1315 Match(a, b) | Reject(a, b)
1316 if a <= b && a == first_index => {
1326 if let Some(err) = err {
1327 panic!("Input skipped range at {}", err);
1330 if first_index != haystack.len() {
1331 panic!("Did not cover whole input");
1334 assert_eq!(v, right);
1337 make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1344 make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1352 make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1369 make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1374 make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1383 make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1386 make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1388 make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1397 make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1402 make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1410 macro_rules! generate_iterator_test {
1414 ($($arg:expr),*) -> [$($t:tt)*];
1417 with $fwd:expr, $bwd:expr;
1423 let res = vec![$($t)*];
1425 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1426 assert_eq!(fwd_vec, res);
1428 let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1430 assert_eq!(bwd_vec, res);
1438 ($($arg:expr),*) -> [$($t:tt)*];
1447 let res = vec![$($t)*];
1449 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1450 assert_eq!(fwd_vec, res);
1457 generate_iterator_test! {
1458 double_ended_split {
1459 ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1460 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1462 with str::split, str::rsplit;
1465 generate_iterator_test! {
1466 double_ended_split_terminator {
1467 ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1469 with str::split_terminator, str::rsplit_terminator;
1472 generate_iterator_test! {
1473 double_ended_matches {
1474 ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1476 with str::matches, str::rmatches;
1479 generate_iterator_test! {
1480 double_ended_match_indices {
1481 ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1483 with str::match_indices, str::rmatch_indices;
1486 generate_iterator_test! {
1487 not_double_ended_splitn {
1488 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1493 generate_iterator_test! {
1494 not_double_ended_rsplitn {
1495 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1501 use test::{Bencher, black_box};
1504 fn char_iterator(b: &mut Bencher) {
1505 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1507 b.iter(|| s.chars().count());
1511 fn char_iterator_for(b: &mut Bencher) {
1512 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1515 for ch in s.chars() { black_box(ch); }
1520 fn char_iterator_ascii(b: &mut Bencher) {
1521 let s = "Mary had a little lamb, Little lamb
1522 Mary had a little lamb, Little lamb
1523 Mary had a little lamb, Little lamb
1524 Mary had a little lamb, Little lamb
1525 Mary had a little lamb, Little lamb
1526 Mary had a little lamb, Little lamb";
1528 b.iter(|| s.chars().count());
1532 fn char_iterator_rev(b: &mut Bencher) {
1533 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1535 b.iter(|| s.chars().rev().count());
1539 fn char_iterator_rev_for(b: &mut Bencher) {
1540 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1543 for ch in s.chars().rev() { black_box(ch); }
1548 fn char_indicesator(b: &mut Bencher) {
1549 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1550 let len = s.chars().count();
1552 b.iter(|| assert_eq!(s.char_indices().count(), len));
1556 fn char_indicesator_rev(b: &mut Bencher) {
1557 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1558 let len = s.chars().count();
1560 b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
1564 fn split_unicode_ascii(b: &mut Bencher) {
1565 let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
1567 b.iter(|| assert_eq!(s.split('V').count(), 3));
1571 fn split_ascii(b: &mut Bencher) {
1572 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1573 let len = s.split(' ').count();
1575 b.iter(|| assert_eq!(s.split(' ').count(), len));
1579 fn split_extern_fn(b: &mut Bencher) {
1580 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1581 let len = s.split(' ').count();
1582 fn pred(c: char) -> bool { c == ' ' }
1584 b.iter(|| assert_eq!(s.split(pred).count(), len));
1588 fn split_closure(b: &mut Bencher) {
1589 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1590 let len = s.split(' ').count();
1592 b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
1596 fn split_slice(b: &mut Bencher) {
1597 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1598 let len = s.split(' ').count();
1600 let c: &[char] = &[' '];
1601 b.iter(|| assert_eq!(s.split(c).count(), len));
1605 fn bench_join(b: &mut Bencher) {
1606 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1608 let v = vec![s, s, s, s, s, s, s, s, s, s];
1610 assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9);
1615 fn bench_contains_short_short(b: &mut Bencher) {
1616 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1620 assert!(haystack.contains(needle));
1625 fn bench_contains_short_long(b: &mut Bencher) {
1627 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1628 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1629 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1630 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1631 tempus vel, gravida nec quam.
1633 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1634 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1635 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1636 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1637 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1638 interdum. Curabitur ut nisi justo.
1640 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1641 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1642 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1643 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1644 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1645 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1646 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1647 Aliquam sit amet placerat lorem.
1649 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1650 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1651 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1652 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1653 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1656 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1657 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1658 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1659 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1660 malesuada sollicitudin quam eu fermentum.";
1661 let needle = "english";
1664 assert!(!haystack.contains(needle));
1669 fn bench_contains_bad_naive(b: &mut Bencher) {
1670 let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1671 let needle = "aaaaaaaab";
1674 assert!(!haystack.contains(needle));
1679 fn bench_contains_equal(b: &mut Bencher) {
1680 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1681 let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1684 assert!(haystack.contains(needle));
1688 macro_rules! make_test_inner {
1689 ($s:ident, $code:expr, $name:ident, $str:expr) => {
1691 fn $name(bencher: &mut Bencher) {
1694 bencher.iter(|| $code);
1699 macro_rules! make_test {
1700 ($name:ident, $s:ident, $code:expr) => {
1703 use test::black_box;
1705 // Short strings: 65 bytes each
1706 make_test_inner!($s, $code, short_ascii,
1707 "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
1708 make_test_inner!($s, $code, short_mixed,
1709 "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
1710 make_test_inner!($s, $code, short_pile_of_poo,
1711 "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
1712 make_test_inner!($s, $code, long_lorem_ipsum,"\
1713 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1714 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1715 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1716 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1717 tempus vel, gravida nec quam.
1719 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1720 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1721 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1722 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1723 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1724 interdum. Curabitur ut nisi justo.
1726 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1727 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1728 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1729 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1730 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1731 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1732 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1733 Aliquam sit amet placerat lorem.
1735 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1736 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1737 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1738 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1739 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1742 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1743 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1744 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1745 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1746 malesuada sollicitudin quam eu fermentum!");
1751 make_test!(chars_count, s, s.chars().count());
1753 make_test!(contains_bang_str, s, s.contains("!"));
1754 make_test!(contains_bang_char, s, s.contains('!'));
1756 make_test!(match_indices_a_str, s, s.match_indices("a").count());
1758 make_test!(split_a_str, s, s.split("a").count());
1760 make_test!(trim_ascii_char, s, {
1761 use std::ascii::AsciiExt;
1762 s.trim_matches(|c: char| c.is_ascii())
1764 make_test!(trim_left_ascii_char, s, {
1765 use std::ascii::AsciiExt;
1766 s.trim_left_matches(|c: char| c.is_ascii())
1768 make_test!(trim_right_ascii_char, s, {
1769 use std::ascii::AsciiExt;
1770 s.trim_right_matches(|c: char| c.is_ascii())
1773 make_test!(find_underscore_char, s, s.find('_'));
1774 make_test!(rfind_underscore_char, s, s.rfind('_'));
1775 make_test!(find_underscore_str, s, s.find("_"));
1777 make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
1778 make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
1779 make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
1781 make_test!(split_space_char, s, s.split(' ').count());
1782 make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
1784 make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
1785 make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
1787 make_test!(split_space_str, s, s.split(" ").count());
1788 make_test!(split_ad_str, s, s.split("ad").count());