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);
274 assert_eq!("ab", &"abc"[0..2]);
275 assert_eq!("bc", &"abc"[1..3]);
276 assert_eq!("", &"abc"[1..1]);
277 assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
279 let data = "ประเทศไทย中华";
280 assert_eq!("ป", &data[0..3]);
281 assert_eq!("ร", &data[3..6]);
282 assert_eq!("", &data[3..3]);
283 assert_eq!("华", &data[30..33]);
285 fn a_million_letter_x() -> String {
287 let mut rs = String::new();
289 rs.push_str("华华华华华华华华华华");
294 fn half_a_million_letter_x() -> String {
296 let mut rs = String::new();
298 rs.push_str("华华华华华");
303 let letters = a_million_letter_x();
304 assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
309 let ss = "中华Việt Nam";
311 assert_eq!("华", &ss[3..6]);
312 assert_eq!("Việt Nam", &ss[6..16]);
314 assert_eq!("ab", &"abc"[0..2]);
315 assert_eq!("bc", &"abc"[1..3]);
316 assert_eq!("", &"abc"[1..1]);
318 assert_eq!("中", &ss[0..3]);
319 assert_eq!("华V", &ss[3..7]);
320 assert_eq!("", &ss[3..3]);
335 fn test_slice_fail() {
340 fn test_slice_from() {
341 assert_eq!(&"abcd"[0..], "abcd");
342 assert_eq!(&"abcd"[2..], "cd");
343 assert_eq!(&"abcd"[4..], "");
347 assert_eq!(&"abcd"[..0], "");
348 assert_eq!(&"abcd"[..2], "ab");
349 assert_eq!(&"abcd"[..4], "abcd");
353 fn test_trim_left_matches() {
354 let v: &[char] = &[];
355 assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
356 let chars: &[char] = &['*', ' '];
357 assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
358 assert_eq!(" *** *** ".trim_left_matches(chars), "");
359 assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
361 assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
362 let chars: &[char] = &['1', '2'];
363 assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
364 assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
368 fn test_trim_right_matches() {
369 let v: &[char] = &[];
370 assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
371 let chars: &[char] = &['*', ' '];
372 assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
373 assert_eq!(" *** *** ".trim_right_matches(chars), "");
374 assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
376 assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
377 let chars: &[char] = &['1', '2'];
378 assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
379 assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
383 fn test_trim_matches() {
384 let v: &[char] = &[];
385 assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
386 let chars: &[char] = &['*', ' '];
387 assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
388 assert_eq!(" *** *** ".trim_matches(chars), "");
389 assert_eq!("foo".trim_matches(chars), "foo");
391 assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
392 let chars: &[char] = &['1', '2'];
393 assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
394 assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
398 fn test_trim_left() {
399 assert_eq!("".trim_left(), "");
400 assert_eq!("a".trim_left(), "a");
401 assert_eq!(" ".trim_left(), "");
402 assert_eq!(" blah".trim_left(), "blah");
403 assert_eq!(" \u{3000} wut".trim_left(), "wut");
404 assert_eq!("hey ".trim_left(), "hey ");
408 fn test_trim_right() {
409 assert_eq!("".trim_right(), "");
410 assert_eq!("a".trim_right(), "a");
411 assert_eq!(" ".trim_right(), "");
412 assert_eq!("blah ".trim_right(), "blah");
413 assert_eq!("wut \u{3000} ".trim_right(), "wut");
414 assert_eq!(" hey".trim_right(), " hey");
419 assert_eq!("".trim(), "");
420 assert_eq!("a".trim(), "a");
421 assert_eq!(" ".trim(), "");
422 assert_eq!(" blah ".trim(), "blah");
423 assert_eq!("\nwut \u{3000} ".trim(), "wut");
424 assert_eq!(" hey dude ".trim(), "hey dude");
428 fn test_is_whitespace() {
429 assert!("".chars().all(|c| c.is_whitespace()));
430 assert!(" ".chars().all(|c| c.is_whitespace()));
431 assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
432 assert!(" \n\t ".chars().all(|c| c.is_whitespace()));
433 assert!(!" _ ".chars().all(|c| c.is_whitespace()));
437 fn test_slice_shift_char() {
438 let data = "ประเทศไทย中";
439 assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
443 fn test_slice_shift_char_2() {
445 assert_eq!(empty.slice_shift_char(), None);
450 // deny overlong encodings
451 assert!(from_utf8(&[0xc0, 0x80]).is_err());
452 assert!(from_utf8(&[0xc0, 0xae]).is_err());
453 assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
454 assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
455 assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
456 assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
457 assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
460 assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
461 assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
463 assert!(from_utf8(&[0xC2, 0x80]).is_ok());
464 assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
465 assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
466 assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
467 assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
468 assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
469 assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
470 assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
475 use rustc_unicode::str::is_utf16;
478 ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
487 // surrogate pairs (randomly generated with Python 3's
488 // .encode('utf-16be'))
489 pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
490 &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
491 &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
493 // mixtures (also random)
494 pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
495 &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
496 &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
500 ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
504 // surrogate + regular unit
506 // surrogate + lead surrogate
508 // unterminated surrogate
510 // trail surrogate without a lead
513 // random byte sequences that Python 3's .decode('utf-16be')
515 neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
516 &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
517 &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
518 &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
519 &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
520 &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
521 &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
522 &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
523 &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
524 &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
525 &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
526 &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
527 &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
528 &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
529 &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
530 &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
531 &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
532 &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
533 &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
534 &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
535 &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
542 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
543 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
547 assert_eq!("".as_bytes(), b);
548 assert_eq!("abc".as_bytes(), b"abc");
549 assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
554 fn test_as_bytes_fail() {
555 // Don't double free. (I'm not sure if this exercises the
556 // original problem code path anymore.)
557 let s = String::from("");
558 let _bytes = s.as_bytes();
564 let buf = "hello".as_ptr();
566 assert_eq!(*buf.offset(0), b'h');
567 assert_eq!(*buf.offset(1), b'e');
568 assert_eq!(*buf.offset(2), b'l');
569 assert_eq!(*buf.offset(3), b'l');
570 assert_eq!(*buf.offset(4), b'o');
575 fn vec_str_conversions() {
576 let s1: String = String::from("All mimsy were the borogoves");
578 let v: Vec<u8> = s1.as_bytes().to_vec();
579 let s2: String = String::from(from_utf8(&v).unwrap());
585 let a: u8 = s1.as_bytes()[i];
586 let b: u8 = s2.as_bytes()[i];
596 assert!("abcde".contains("bcd"));
597 assert!("abcde".contains("abcd"));
598 assert!("abcde".contains("bcde"));
599 assert!("abcde".contains(""));
600 assert!("".contains(""));
601 assert!(!"abcde".contains("def"));
602 assert!(!"".contains("a"));
604 let data = "ประเทศไทย中华Việt Nam";
605 assert!(data.contains("ประเ"));
606 assert!(data.contains("ะเ"));
607 assert!(data.contains("中华"));
608 assert!(!data.contains("ไท华"));
612 fn test_contains_char() {
613 assert!("abc".contains('b'));
614 assert!("a".contains('a'));
615 assert!(!"abc".contains('d'));
616 assert!(!"".contains('a'));
621 let s = "ศไทย中华Việt Nam";
622 let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
625 assert!(s.char_at(pos) == *ch);
626 pos += ch.to_string().len();
631 fn test_char_at_reverse() {
632 let s = "ศไทย中华Việt Nam";
633 let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
634 let mut pos = s.len();
635 for ch in v.iter().rev() {
636 assert!(s.char_at_reverse(pos) == *ch);
637 pos -= ch.to_string().len();
643 let s = "ศไทย中华Việt Nam";
644 for (index, _) in s.char_indices() {
645 let (a, b) = s.split_at(index);
646 assert_eq!(&s[..a.len()], a);
647 assert_eq!(&s[a.len()..], b);
649 let (a, b) = s.split_at(s.len());
655 fn test_split_at_mut() {
656 use std::ascii::AsciiExt;
657 let mut s = "Hello World".to_string();
659 let (a, b) = s.split_at_mut(5);
660 a.make_ascii_uppercase();
661 b.make_ascii_lowercase();
663 assert_eq!(s, "HELLO world");
668 fn test_split_at_boundscheck() {
669 let s = "ศไทย中华Việt Nam";
674 fn test_escape_unicode() {
675 assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
676 assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
677 assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
678 assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
679 assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
680 assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
681 assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
682 assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
683 assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
687 fn test_escape_default() {
688 assert_eq!("abc".escape_default(), "abc");
689 assert_eq!("a c".escape_default(), "a c");
690 assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
691 assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
692 assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
693 assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
694 assert_eq!("ab\u{fb00}".escape_default(), "ab\\u{fb00}");
695 assert_eq!("\u{1d4ea}\r".escape_default(), "\\u{1d4ea}\\r");
699 fn test_total_ord() {
700 assert_eq!("1234".cmp("123"), Greater);
701 assert_eq!("123".cmp("1234"), Less);
702 assert_eq!("1234".cmp("1234"), Equal);
703 assert_eq!("12345555".cmp("123456"), Less);
704 assert_eq!("22".cmp("1234"), Greater);
708 fn test_char_range_at() {
709 let data = "b¢€𤭢𤭢€¢b";
710 assert_eq!('b', data.char_range_at(0).ch);
711 assert_eq!('¢', data.char_range_at(1).ch);
712 assert_eq!('€', data.char_range_at(3).ch);
713 assert_eq!('𤭢', data.char_range_at(6).ch);
714 assert_eq!('𤭢', data.char_range_at(10).ch);
715 assert_eq!('€', data.char_range_at(14).ch);
716 assert_eq!('¢', data.char_range_at(17).ch);
717 assert_eq!('b', data.char_range_at(19).ch);
721 fn test_char_range_at_reverse_underflow() {
722 assert_eq!("abc".char_range_at_reverse(0).next, 0);
727 let s = "ศไทย中华Việt Nam";
728 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
734 assert_eq!(c, v[pos]);
737 assert_eq!(pos, v.len());
741 fn test_rev_iterator() {
742 let s = "ศไทย中华Việt Nam";
743 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
746 let it = s.chars().rev();
749 assert_eq!(c, v[pos]);
752 assert_eq!(pos, v.len());
756 fn test_chars_decoding() {
757 let mut bytes = [0; 4];
758 for c in (0..0x110000).filter_map(::std::char::from_u32) {
759 let len = c.encode_utf8(&mut bytes).unwrap_or(0);
760 let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
761 if Some(c) != s.chars().next() {
762 panic!("character {:x}={} does not decode correctly", c as u32, c);
768 fn test_chars_rev_decoding() {
769 let mut bytes = [0; 4];
770 for c in (0..0x110000).filter_map(::std::char::from_u32) {
771 let len = c.encode_utf8(&mut bytes).unwrap_or(0);
772 let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
773 if Some(c) != s.chars().rev().next() {
774 panic!("character {:x}={} does not decode correctly", c as u32, c);
780 fn test_iterator_clone() {
781 let s = "ศไทย中华Việt Nam";
782 let mut it = s.chars();
784 assert!(it.clone().zip(it).all(|(x,y)| x == y));
788 fn test_bytesator() {
789 let s = "ศไทย中华Việt Nam";
791 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
792 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
798 assert_eq!(b, v[pos]);
804 fn test_bytes_revator() {
805 let s = "ศไทย中华Việt Nam";
807 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
808 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
811 let mut pos = v.len();
813 for b in s.bytes().rev() {
815 assert_eq!(b, v[pos]);
820 fn test_bytesator_nth() {
821 let s = "ศไทย中华Việt Nam";
823 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
824 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
828 let mut b = s.bytes();
829 assert_eq!(b.nth(2).unwrap(), v[2]);
830 assert_eq!(b.nth(10).unwrap(), v[10]);
831 assert_eq!(b.nth(200), None);
835 fn test_bytesator_count() {
836 let s = "ศไทย中华Việt Nam";
839 assert_eq!(b.count(), 28)
843 fn test_bytesator_last() {
844 let s = "ศไทย中华Việt Nam";
847 assert_eq!(b.last().unwrap(), 109)
851 fn test_char_indicesator() {
852 let s = "ศไทย中华Việt Nam";
853 let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
854 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
857 let it = s.char_indices();
860 assert_eq!(c, (p[pos], v[pos]));
863 assert_eq!(pos, v.len());
864 assert_eq!(pos, p.len());
868 fn test_char_indices_revator() {
869 let s = "ศไทย中华Việt Nam";
870 let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
871 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
874 let it = s.char_indices().rev();
877 assert_eq!(c, (p[pos], v[pos]));
880 assert_eq!(pos, v.len());
881 assert_eq!(pos, p.len());
885 fn test_splitn_char_iterator() {
886 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
888 let split: Vec<&str> = data.splitn(4, ' ').collect();
889 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
891 let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
892 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
895 let split: Vec<&str> = data.splitn(4, 'ä').collect();
896 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
898 let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
899 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
903 fn test_split_char_iterator_no_trailing() {
904 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
906 let split: Vec<&str> = data.split('\n').collect();
907 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
909 let split: Vec<&str> = data.split_terminator('\n').collect();
910 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
915 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
917 let split: Vec<&str> = data.rsplit(' ').collect();
918 assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
920 let split: Vec<&str> = data.rsplit("lämb").collect();
921 assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
923 let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
924 assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
929 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
931 let split: Vec<&str> = data.rsplitn(2, ' ').collect();
932 assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
934 let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
935 assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
937 let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
938 assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
942 fn test_split_whitespace() {
943 let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
944 let words: Vec<&str> = data.split_whitespace().collect();
945 assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
950 let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
951 let lines: Vec<&str> = data.lines().collect();
952 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
954 let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
955 let lines: Vec<&str> = data.lines().collect();
956 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
960 fn test_splitator() {
961 fn t(s: &str, sep: &str, u: &[&str]) {
962 let v: Vec<&str> = s.split(sep).collect();
965 t("--1233345--", "12345", &["--1233345--"]);
966 t("abc::hello::there", "::", &["abc", "hello", "there"]);
967 t("::hello::there", "::", &["", "hello", "there"]);
968 t("hello::there::", "::", &["hello", "there", ""]);
969 t("::hello::there::", "::", &["", "hello", "there", ""]);
970 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
971 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
972 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
973 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
975 t("zz", "zz", &["",""]);
976 t("ok", "z", &["ok"]);
977 t("zzz", "zz", &["","z"]);
978 t("zzzzz", "zz", &["","","z"]);
982 fn test_str_default() {
983 use std::default::Default;
985 fn t<S: Default + AsRef<str>>() {
986 let s: S = Default::default();
987 assert_eq!(s.as_ref(), "");
995 fn test_str_container() {
996 fn sum_len(v: &[&str]) -> usize {
997 v.iter().map(|x| x.len()).sum()
1001 assert_eq!(5, sum_len(&["012", "", "34"]));
1002 assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1003 assert_eq!(5, sum_len(&[s]));
1007 fn test_str_from_utf8() {
1009 assert_eq!(from_utf8(xs), Ok("hello"));
1011 let xs = "ศไทย中华Việt Nam".as_bytes();
1012 assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1014 let xs = b"hello\xFF";
1015 assert!(from_utf8(xs).is_err());
1019 fn test_pattern_deref_forward() {
1020 let data = "aabcdaa";
1021 assert!(data.contains("bcd"));
1022 assert!(data.contains(&"bcd"));
1023 assert!(data.contains(&"bcd".to_string()));
1027 fn test_empty_match_indices() {
1029 let vec: Vec<_> = data.match_indices("").collect();
1030 assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1034 fn test_bool_from_str() {
1035 assert_eq!("true".parse().ok(), Some(true));
1036 assert_eq!("false".parse().ok(), Some(false));
1037 assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1040 fn check_contains_all_substrings(s: &str) {
1041 assert!(s.contains(""));
1042 for i in 0..s.len() {
1043 for j in i+1..s.len() + 1 {
1044 assert!(s.contains(&s[i..j]));
1050 fn strslice_issue_16589() {
1051 assert!("bananas".contains("nana"));
1053 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1054 // test all substrings for good measure
1055 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1059 fn strslice_issue_16878() {
1060 assert!(!"1234567ah012345678901ah".contains("hah"));
1061 assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1066 fn test_strslice_contains() {
1067 let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1068 check_contains_all_substrings(x);
1072 fn test_rsplitn_char_iterator() {
1073 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1075 let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1077 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1079 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1081 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1084 let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1086 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1088 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1090 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1094 fn test_split_char_iterator() {
1095 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1097 let split: Vec<&str> = data.split(' ').collect();
1098 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1100 let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1102 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1104 let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1105 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1107 let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1109 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1112 let split: Vec<&str> = data.split('ä').collect();
1113 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1115 let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1117 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1119 let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1120 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1122 let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1124 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1128 fn test_rev_split_char_iterator_no_trailing() {
1129 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1131 let mut split: Vec<&str> = data.split('\n').rev().collect();
1133 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1135 let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1137 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1141 fn test_utf16_code_units() {
1142 use rustc_unicode::str::Utf16Encoder;
1143 assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1144 [0xE9, 0xD83D, 0xDCA9])
1148 fn starts_with_in_unicode() {
1149 assert!(!"├── Cargo.toml".starts_with("# "));
1153 fn starts_short_long() {
1154 assert!(!"".starts_with("##"));
1155 assert!(!"##".starts_with("####"));
1156 assert!("####".starts_with("##"));
1157 assert!(!"##ä".starts_with("####"));
1158 assert!("####ä".starts_with("##"));
1159 assert!(!"##".starts_with("####ä"));
1160 assert!("##ä##".starts_with("##ä"));
1162 assert!("".starts_with(""));
1163 assert!("ä".starts_with(""));
1164 assert!("#ä".starts_with(""));
1165 assert!("##ä".starts_with(""));
1166 assert!("ä###".starts_with(""));
1167 assert!("#ä##".starts_with(""));
1168 assert!("##ä#".starts_with(""));
1172 fn contains_weird_cases() {
1173 assert!("* \t".contains(' '));
1174 assert!(!"* \t".contains('?'));
1175 assert!(!"* \t".contains('\u{1F4A9}'));
1180 assert_eq!(" \t a \t ".trim_left_matches(|c: char| c.is_whitespace()),
1182 assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()),
1184 assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()),
1186 assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()),
1188 assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()),
1190 assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()),
1196 assert_eq!("".to_lowercase(), "");
1197 assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1199 // https://github.com/rust-lang/rust/issues/26035
1200 assert_eq!("ΑΣ".to_lowercase(), "ας");
1201 assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1202 assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1204 assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1205 assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1206 assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1208 assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1209 assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1211 assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1212 assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1214 assert_eq!("Α Σ".to_lowercase(), "α σ");
1215 assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1216 assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1218 assert_eq!("Σ".to_lowercase(), "σ");
1219 assert_eq!("'Σ".to_lowercase(), "'σ");
1220 assert_eq!("''Σ".to_lowercase(), "''σ");
1222 assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1223 assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1224 assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1229 assert_eq!("".to_uppercase(), "");
1230 assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1234 fn test_into_string() {
1235 // The only way to acquire a Box<str> in the first place is through a String, so just
1236 // test that we can round-trip between Box<str> and String.
1237 let string = String::from("Some text goes here");
1238 assert_eq!(string.clone().into_boxed_str().into_string(), string);
1242 fn test_box_slice_clone() {
1243 let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1244 let data2 = data.clone().into_boxed_str().clone().into_string();
1246 assert_eq!(data, data2);
1250 use std::str::pattern::Pattern;
1251 use std::str::pattern::{Searcher, ReverseSearcher};
1252 use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1254 macro_rules! make_test {
1255 ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1256 #[allow(unused_imports)]
1258 use std::str::pattern::SearchStep::{Match, Reject};
1259 use super::{cmp_search_to_vec};
1262 cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1266 cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1272 fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1273 right: Vec<SearchStep>)
1274 where P::Searcher: ReverseSearcher<'a>
1276 let mut searcher = pat.into_searcher(haystack);
1279 match if !rev {searcher.next()} else {searcher.next_back()} {
1280 Match(a, b) => v.push(Match(a, b)),
1281 Reject(a, b) => v.push(Reject(a, b)),
1289 let mut first_index = 0;
1292 for (i, e) in right.iter().enumerate() {
1294 Match(a, b) | Reject(a, b)
1295 if a <= b && a == first_index => {
1305 if let Some(err) = err {
1306 panic!("Input skipped range at {}", err);
1309 if first_index != haystack.len() {
1310 panic!("Did not cover whole input");
1313 assert_eq!(v, right);
1316 make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1323 make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1331 make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1348 make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1353 make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1362 make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1365 make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1367 make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1376 make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1381 make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1389 macro_rules! generate_iterator_test {
1393 ($($arg:expr),*) -> [$($t:tt)*];
1396 with $fwd:expr, $bwd:expr;
1402 let res = vec![$($t)*];
1404 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1405 assert_eq!(fwd_vec, res);
1407 let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1409 assert_eq!(bwd_vec, res);
1417 ($($arg:expr),*) -> [$($t:tt)*];
1426 let res = vec![$($t)*];
1428 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1429 assert_eq!(fwd_vec, res);
1436 generate_iterator_test! {
1437 double_ended_split {
1438 ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1439 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1441 with str::split, str::rsplit;
1444 generate_iterator_test! {
1445 double_ended_split_terminator {
1446 ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1448 with str::split_terminator, str::rsplit_terminator;
1451 generate_iterator_test! {
1452 double_ended_matches {
1453 ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1455 with str::matches, str::rmatches;
1458 generate_iterator_test! {
1459 double_ended_match_indices {
1460 ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1462 with str::match_indices, str::rmatch_indices;
1465 generate_iterator_test! {
1466 not_double_ended_splitn {
1467 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1472 generate_iterator_test! {
1473 not_double_ended_rsplitn {
1474 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1480 use test::{Bencher, black_box};
1483 fn char_iterator(b: &mut Bencher) {
1484 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1486 b.iter(|| s.chars().count());
1490 fn char_iterator_for(b: &mut Bencher) {
1491 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1494 for ch in s.chars() { black_box(ch); }
1499 fn char_iterator_ascii(b: &mut Bencher) {
1500 let s = "Mary had a little lamb, Little lamb
1501 Mary had a little lamb, Little lamb
1502 Mary had a little lamb, Little lamb
1503 Mary had a little lamb, Little lamb
1504 Mary had a little lamb, Little lamb
1505 Mary had a little lamb, Little lamb";
1507 b.iter(|| s.chars().count());
1511 fn char_iterator_rev(b: &mut Bencher) {
1512 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1514 b.iter(|| s.chars().rev().count());
1518 fn char_iterator_rev_for(b: &mut Bencher) {
1519 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1522 for ch in s.chars().rev() { black_box(ch); }
1527 fn char_indicesator(b: &mut Bencher) {
1528 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1529 let len = s.chars().count();
1531 b.iter(|| assert_eq!(s.char_indices().count(), len));
1535 fn char_indicesator_rev(b: &mut Bencher) {
1536 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1537 let len = s.chars().count();
1539 b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
1543 fn split_unicode_ascii(b: &mut Bencher) {
1544 let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
1546 b.iter(|| assert_eq!(s.split('V').count(), 3));
1550 fn split_ascii(b: &mut Bencher) {
1551 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1552 let len = s.split(' ').count();
1554 b.iter(|| assert_eq!(s.split(' ').count(), len));
1558 fn split_extern_fn(b: &mut Bencher) {
1559 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1560 let len = s.split(' ').count();
1561 fn pred(c: char) -> bool { c == ' ' }
1563 b.iter(|| assert_eq!(s.split(pred).count(), len));
1567 fn split_closure(b: &mut Bencher) {
1568 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1569 let len = s.split(' ').count();
1571 b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
1575 fn split_slice(b: &mut Bencher) {
1576 let s = "Mary had a little lamb, Little lamb, little-lamb.";
1577 let len = s.split(' ').count();
1579 let c: &[char] = &[' '];
1580 b.iter(|| assert_eq!(s.split(c).count(), len));
1584 fn bench_join(b: &mut Bencher) {
1585 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1587 let v = vec![s, s, s, s, s, s, s, s, s, s];
1589 assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9);
1594 fn bench_contains_short_short(b: &mut Bencher) {
1595 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1599 assert!(haystack.contains(needle));
1604 fn bench_contains_short_long(b: &mut Bencher) {
1606 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1607 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1608 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1609 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1610 tempus vel, gravida nec quam.
1612 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1613 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1614 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1615 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1616 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1617 interdum. Curabitur ut nisi justo.
1619 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1620 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1621 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1622 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1623 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1624 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1625 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1626 Aliquam sit amet placerat lorem.
1628 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1629 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1630 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1631 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1632 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1635 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1636 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1637 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1638 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1639 malesuada sollicitudin quam eu fermentum.";
1640 let needle = "english";
1643 assert!(!haystack.contains(needle));
1648 fn bench_contains_bad_naive(b: &mut Bencher) {
1649 let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1650 let needle = "aaaaaaaab";
1653 assert!(!haystack.contains(needle));
1658 fn bench_contains_equal(b: &mut Bencher) {
1659 let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1660 let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1663 assert!(haystack.contains(needle));
1667 macro_rules! make_test_inner {
1668 ($s:ident, $code:expr, $name:ident, $str:expr) => {
1670 fn $name(bencher: &mut Bencher) {
1673 bencher.iter(|| $code);
1678 macro_rules! make_test {
1679 ($name:ident, $s:ident, $code:expr) => {
1682 use test::black_box;
1684 // Short strings: 65 bytes each
1685 make_test_inner!($s, $code, short_ascii,
1686 "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
1687 make_test_inner!($s, $code, short_mixed,
1688 "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
1689 make_test_inner!($s, $code, short_pile_of_poo,
1690 "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
1691 make_test_inner!($s, $code, long_lorem_ipsum,"\
1692 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1693 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1694 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1695 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1696 tempus vel, gravida nec quam.
1698 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1699 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1700 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1701 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1702 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1703 interdum. Curabitur ut nisi justo.
1705 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1706 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1707 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1708 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1709 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1710 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1711 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1712 Aliquam sit amet placerat lorem.
1714 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1715 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1716 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1717 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1718 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1721 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1722 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1723 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1724 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1725 malesuada sollicitudin quam eu fermentum!");
1730 make_test!(chars_count, s, s.chars().count());
1732 make_test!(contains_bang_str, s, s.contains("!"));
1733 make_test!(contains_bang_char, s, s.contains('!'));
1735 make_test!(match_indices_a_str, s, s.match_indices("a").count());
1737 make_test!(split_a_str, s, s.split("a").count());
1739 make_test!(trim_ascii_char, s, {
1740 use std::ascii::AsciiExt;
1741 s.trim_matches(|c: char| c.is_ascii())
1743 make_test!(trim_left_ascii_char, s, {
1744 use std::ascii::AsciiExt;
1745 s.trim_left_matches(|c: char| c.is_ascii())
1747 make_test!(trim_right_ascii_char, s, {
1748 use std::ascii::AsciiExt;
1749 s.trim_right_matches(|c: char| c.is_ascii())
1752 make_test!(find_underscore_char, s, s.find('_'));
1753 make_test!(rfind_underscore_char, s, s.rfind('_'));
1754 make_test!(find_underscore_str, s, s.find("_"));
1756 make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
1757 make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
1758 make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
1760 make_test!(split_space_char, s, s.split(' ').count());
1761 make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
1763 make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
1764 make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
1766 make_test!(split_space_str, s, s.split(" ").count());
1767 make_test!(split_ad_str, s, s.split("ad").count());