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