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() {
349 const LOREM_PARAGRAPH
: &'
static str = "\
350 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
351 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
352 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
353 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
354 tempus vel, gravida nec quam.";
356 // check the panic includes the prefix of the sliced string
358 #[should_panic(expected="Lorem ipsum dolor sit amet")]
359 fn test_slice_fail_truncated_1() {
360 &LOREM_PARAGRAPH
[..1024];
362 // check the truncation in the panic message
364 #[should_panic(expected="luctus, im`[...] do not lie on character boundary")]
365 fn test_slice_fail_truncated_2() {
366 &LOREM_PARAGRAPH
[..1024];
370 fn test_slice_from() {
371 assert_eq
!(&"abcd"[0..], "abcd");
372 assert_eq
!(&"abcd"[2..], "cd");
373 assert_eq
!(&"abcd"[4..], "");
377 assert_eq
!(&"abcd"[..0], "");
378 assert_eq
!(&"abcd"[..2], "ab");
379 assert_eq
!(&"abcd"[..4], "abcd");
383 fn test_trim_left_matches() {
384 let v
: &[char] = &[];
385 assert_eq
!(" *** foo *** ".trim_left_matches(v
), " *** foo *** ");
386 let chars
: &[char] = &['
*'
, ' '
];
387 assert_eq
!(" *** foo *** ".trim_left_matches(chars
), "foo *** ");
388 assert_eq
!(" *** *** ".trim_left_matches(chars
), "");
389 assert_eq
!("foo *** ".trim_left_matches(chars
), "foo *** ");
391 assert_eq
!("11foo1bar11".trim_left_matches('
1'
), "foo1bar11");
392 let chars
: &[char] = &['
1'
, '
2'
];
393 assert_eq
!("12foo1bar12".trim_left_matches(chars
), "foo1bar12");
394 assert_eq
!("123foo1bar123".trim_left_matches(|c
: char| c
.is_numeric()), "foo1bar123");
398 fn test_trim_right_matches() {
399 let v
: &[char] = &[];
400 assert_eq
!(" *** foo *** ".trim_right_matches(v
), " *** foo *** ");
401 let chars
: &[char] = &['
*'
, ' '
];
402 assert_eq
!(" *** foo *** ".trim_right_matches(chars
), " *** foo");
403 assert_eq
!(" *** *** ".trim_right_matches(chars
), "");
404 assert_eq
!(" *** foo".trim_right_matches(chars
), " *** foo");
406 assert_eq
!("11foo1bar11".trim_right_matches('
1'
), "11foo1bar");
407 let chars
: &[char] = &['
1'
, '
2'
];
408 assert_eq
!("12foo1bar12".trim_right_matches(chars
), "12foo1bar");
409 assert_eq
!("123foo1bar123".trim_right_matches(|c
: char| c
.is_numeric()), "123foo1bar");
413 fn test_trim_matches() {
414 let v
: &[char] = &[];
415 assert_eq
!(" *** foo *** ".trim_matches(v
), " *** foo *** ");
416 let chars
: &[char] = &['
*'
, ' '
];
417 assert_eq
!(" *** foo *** ".trim_matches(chars
), "foo");
418 assert_eq
!(" *** *** ".trim_matches(chars
), "");
419 assert_eq
!("foo".trim_matches(chars
), "foo");
421 assert_eq
!("11foo1bar11".trim_matches('
1'
), "foo1bar");
422 let chars
: &[char] = &['
1'
, '
2'
];
423 assert_eq
!("12foo1bar12".trim_matches(chars
), "foo1bar");
424 assert_eq
!("123foo1bar123".trim_matches(|c
: char| c
.is_numeric()), "foo1bar");
428 fn test_trim_left() {
429 assert_eq
!("".trim_left(), "");
430 assert_eq
!("a".trim_left(), "a");
431 assert_eq
!(" ".trim_left(), "");
432 assert_eq
!(" blah".trim_left(), "blah");
433 assert_eq
!(" \u{3000} wut".trim_left(), "wut");
434 assert_eq
!("hey ".trim_left(), "hey ");
438 fn test_trim_right() {
439 assert_eq
!("".trim_right(), "");
440 assert_eq
!("a".trim_right(), "a");
441 assert_eq
!(" ".trim_right(), "");
442 assert_eq
!("blah ".trim_right(), "blah");
443 assert_eq
!("wut \u{3000} ".trim_right(), "wut");
444 assert_eq
!(" hey".trim_right(), " hey");
449 assert_eq
!("".trim(), "");
450 assert_eq
!("a".trim(), "a");
451 assert_eq
!(" ".trim(), "");
452 assert_eq
!(" blah ".trim(), "blah");
453 assert_eq
!("\nwut \u{3000} ".trim(), "wut");
454 assert_eq
!(" hey dude ".trim(), "hey dude");
458 fn test_is_whitespace() {
459 assert
!("".chars().all(|c
| c
.is_whitespace()));
460 assert
!(" ".chars().all(|c
| c
.is_whitespace()));
461 assert
!("\u{2009}".chars().all(|c
| c
.is_whitespace())); // Thin space
462 assert
!(" \n\t ".chars().all(|c
| c
.is_whitespace()));
463 assert
!(!" _ ".chars().all(|c
| c
.is_whitespace()));
468 fn test_slice_shift_char() {
469 let data
= "ประเทศไทย中";
470 assert_eq
!(data
.slice_shift_char(), Some(('ป'
, "ระเทศไทย中")));
475 fn test_slice_shift_char_2() {
477 assert_eq
!(empty
.slice_shift_char(), None
);
482 // deny overlong encodings
483 assert
!(from_utf8(&[0xc0, 0x80]).is_err());
484 assert
!(from_utf8(&[0xc0, 0xae]).is_err());
485 assert
!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
486 assert
!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
487 assert
!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
488 assert
!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
489 assert
!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
492 assert
!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
493 assert
!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
495 assert
!(from_utf8(&[0xC2, 0x80]).is_ok());
496 assert
!(from_utf8(&[0xDF, 0xBF]).is_ok());
497 assert
!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
498 assert
!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
499 assert
!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
500 assert
!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
501 assert
!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
502 assert
!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
506 fn from_utf8_mostly_ascii() {
507 // deny invalid bytes embedded in long stretches of ascii
509 let mut data
= [0; 128];
511 assert
!(from_utf8(&data
).is_err());
513 assert
!(from_utf8(&data
).is_err());
519 use rustc_unicode
::str::is_utf16
;
522 ($
($e
:expr
),*) => { { $(assert!(is_utf16($e));)* }
}
531 // surrogate pairs (randomly generated with Python 3's
532 // .encode('utf-16be'))
533 pos
!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
534 &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
535 &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
537 // mixtures (also random)
538 pos
!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
539 &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
540 &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
544 ($
($e
:expr
),*) => { { $(assert!(!is_utf16($e));)* }
}
548 // surrogate + regular unit
550 // surrogate + lead surrogate
552 // unterminated surrogate
554 // trail surrogate without a lead
557 // random byte sequences that Python 3's .decode('utf-16be')
559 neg
!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
560 &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
561 &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
562 &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
563 &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
564 &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
565 &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
566 &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
567 &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
568 &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
569 &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
570 &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
571 &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
572 &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
573 &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
574 &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
575 &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
576 &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
577 &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
578 &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
579 &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
586 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
587 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
591 assert_eq
!("".as_bytes(), b
);
592 assert_eq
!("abc".as_bytes(), b
"abc");
593 assert_eq
!("ศไทย中华Việt Nam".as_bytes(), v
);
598 fn test_as_bytes_fail() {
599 // Don't double free. (I'm not sure if this exercises the
600 // original problem code path anymore.)
601 let s
= String
::from("");
602 let _bytes
= s
.as_bytes();
608 let buf
= "hello".as_ptr();
610 assert_eq
!(*buf
.offset(0), b'h'
);
611 assert_eq
!(*buf
.offset(1), b'e'
);
612 assert_eq
!(*buf
.offset(2), b'l'
);
613 assert_eq
!(*buf
.offset(3), b'l'
);
614 assert_eq
!(*buf
.offset(4), b'o'
);
619 fn vec_str_conversions() {
620 let s1
: String
= String
::from("All mimsy were the borogoves");
622 let v
: Vec
<u8> = s1
.as_bytes().to_vec();
623 let s2
: String
= String
::from(from_utf8(&v
).unwrap());
629 let a
: u8 = s1
.as_bytes()[i
];
630 let b
: u8 = s2
.as_bytes()[i
];
638 assert
!("abcde".contains("bcd"));
639 assert
!("abcde".contains("abcd"));
640 assert
!("abcde".contains("bcde"));
641 assert
!("abcde".contains(""));
642 assert
!("".contains(""));
643 assert
!(!"abcde".contains("def"));
644 assert
!(!"".contains("a"));
646 let data
= "ประเทศไทย中华Việt Nam";
647 assert
!(data
.contains("ประเ"));
648 assert
!(data
.contains("ะเ"));
649 assert
!(data
.contains("中华"));
650 assert
!(!data
.contains("ไท华"));
654 fn test_contains_char() {
655 assert
!("abc".contains('b'
));
656 assert
!("a".contains('a'
));
657 assert
!(!"abc".contains('d'
));
658 assert
!(!"".contains('a'
));
664 let s
= "ศไทย中华Việt Nam";
665 let v
= vec
!['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
668 assert
!(s
.char_at(pos
) == *ch
);
669 pos
+= ch
.to_string().len();
675 fn test_char_at_reverse() {
676 let s
= "ศไทย中华Việt Nam";
677 let v
= vec
!['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
678 let mut pos
= s
.len();
679 for ch
in v
.iter().rev() {
680 assert
!(s
.char_at_reverse(pos
) == *ch
);
681 pos
-= ch
.to_string().len();
687 let s
= "ศไทย中华Việt Nam";
688 for (index
, _
) in s
.char_indices() {
689 let (a
, b
) = s
.split_at(index
);
690 assert_eq
!(&s
[..a
.len()], a
);
691 assert_eq
!(&s
[a
.len()..], b
);
693 let (a
, b
) = s
.split_at(s
.len());
699 fn test_split_at_mut() {
700 use std
::ascii
::AsciiExt
;
701 let mut s
= "Hello World".to_string();
703 let (a
, b
) = s
.split_at_mut(5);
704 a
.make_ascii_uppercase();
705 b
.make_ascii_lowercase();
707 assert_eq
!(s
, "HELLO world");
712 fn test_split_at_boundscheck() {
713 let s
= "ศไทย中华Việt Nam";
718 fn test_escape_unicode() {
719 assert_eq
!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
720 assert_eq
!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
721 assert_eq
!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
722 assert_eq
!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
723 assert_eq
!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
724 assert_eq
!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
725 assert_eq
!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
726 assert_eq
!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
727 assert_eq
!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
731 fn test_escape_default() {
732 assert_eq
!("abc".escape_default(), "abc");
733 assert_eq
!("a c".escape_default(), "a c");
734 assert_eq
!("\r\n\t".escape_default(), "\\r\\n\\t");
735 assert_eq
!("'\"\\".escape_default(), "\\'\\\"\\\\");
736 assert_eq
!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
737 assert_eq
!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
738 assert_eq
!("ab\u{fb00}".escape_default(), "ab\\u{fb00}");
739 assert_eq
!("\u{1d4ea}\r".escape_default(), "\\u{1d4ea}\\r");
743 fn test_total_ord() {
744 assert_eq
!("1234".cmp("123"), Greater
);
745 assert_eq
!("123".cmp("1234"), Less
);
746 assert_eq
!("1234".cmp("1234"), Equal
);
747 assert_eq
!("12345555".cmp("123456"), Less
);
748 assert_eq
!("22".cmp("1234"), Greater
);
753 fn test_char_range_at() {
754 let data
= "b¢€𤭢𤭢€¢b";
755 assert_eq
!('b'
, data
.char_range_at(0).ch
);
756 assert_eq
!('¢'
, data
.char_range_at(1).ch
);
757 assert_eq
!('€'
, data
.char_range_at(3).ch
);
758 assert_eq
!('𤭢'
, data
.char_range_at(6).ch
);
759 assert_eq
!('𤭢'
, data
.char_range_at(10).ch
);
760 assert_eq
!('€'
, data
.char_range_at(14).ch
);
761 assert_eq
!('¢'
, data
.char_range_at(17).ch
);
762 assert_eq
!('b'
, data
.char_range_at(19).ch
);
767 fn test_char_range_at_reverse_underflow() {
768 assert_eq
!("abc".char_range_at_reverse(0).next
, 0);
773 let s
= "ศไทย中华Việt Nam";
774 let v
= ['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
780 assert_eq
!(c
, v
[pos
]);
783 assert_eq
!(pos
, v
.len());
787 fn test_rev_iterator() {
788 let s
= "ศไทย中华Việt Nam";
789 let v
= ['m'
, 'a'
, 'N'
, ' '
, 't'
, 'ệ'
,'i'
,'V'
,'华'
,'中'
,'ย'
,'ท'
,'ไ'
,'ศ'
];
792 let it
= s
.chars().rev();
795 assert_eq
!(c
, v
[pos
]);
798 assert_eq
!(pos
, v
.len());
802 fn test_chars_decoding() {
803 for c
in (0..0x110000).filter_map(::std
::char::from_u32
) {
804 let bytes
= c
.encode_utf8();
805 let s
= ::std
::str::from_utf8(bytes
.as_slice()).unwrap();
806 if Some(c
) != s
.chars().next() {
807 panic
!("character {:x}={} does not decode correctly", c
as u32, c
);
813 fn test_chars_rev_decoding() {
814 for c
in (0..0x110000).filter_map(::std
::char::from_u32
) {
815 let bytes
= c
.encode_utf8();
816 let s
= ::std
::str::from_utf8(bytes
.as_slice()).unwrap();
817 if Some(c
) != s
.chars().rev().next() {
818 panic
!("character {:x}={} does not decode correctly", c
as u32, c
);
824 fn test_iterator_clone() {
825 let s
= "ศไทย中华Việt Nam";
826 let mut it
= s
.chars();
828 assert
!(it
.clone().zip(it
).all(|(x
,y
)| x
== y
));
832 fn test_bytesator() {
833 let s
= "ศไทย中华Việt Nam";
835 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
836 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
842 assert_eq
!(b
, v
[pos
]);
848 fn test_bytes_revator() {
849 let s
= "ศไทย中华Việt Nam";
851 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
852 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
855 let mut pos
= v
.len();
857 for b
in s
.bytes().rev() {
859 assert_eq
!(b
, v
[pos
]);
864 fn test_bytesator_nth() {
865 let s
= "ศไทย中华Việt Nam";
867 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
868 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
872 let mut b
= s
.bytes();
873 assert_eq
!(b
.nth(2).unwrap(), v
[2]);
874 assert_eq
!(b
.nth(10).unwrap(), v
[10]);
875 assert_eq
!(b
.nth(200), None
);
879 fn test_bytesator_count() {
880 let s
= "ศไทย中华Việt Nam";
883 assert_eq
!(b
.count(), 28)
887 fn test_bytesator_last() {
888 let s
= "ศไทย中华Việt Nam";
891 assert_eq
!(b
.last().unwrap(), 109)
895 fn test_char_indicesator() {
896 let s
= "ศไทย中华Việt Nam";
897 let p
= [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
898 let v
= ['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
901 let it
= s
.char_indices();
904 assert_eq
!(c
, (p
[pos
], v
[pos
]));
907 assert_eq
!(pos
, v
.len());
908 assert_eq
!(pos
, p
.len());
912 fn test_char_indices_revator() {
913 let s
= "ศไทย中华Việt Nam";
914 let p
= [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
915 let v
= ['m'
, 'a'
, 'N'
, ' '
, 't'
, 'ệ'
,'i'
,'V'
,'华'
,'中'
,'ย'
,'ท'
,'ไ'
,'ศ'
];
918 let it
= s
.char_indices().rev();
921 assert_eq
!(c
, (p
[pos
], v
[pos
]));
924 assert_eq
!(pos
, v
.len());
925 assert_eq
!(pos
, p
.len());
929 fn test_splitn_char_iterator() {
930 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
932 let split
: Vec
<&str> = data
.splitn(4, ' '
).collect();
933 assert_eq
!(split
, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
935 let split
: Vec
<&str> = data
.splitn(4, |c
: char| c
== ' '
).collect();
936 assert_eq
!(split
, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
939 let split
: Vec
<&str> = data
.splitn(4, 'ä'
).collect();
940 assert_eq
!(split
, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
942 let split
: Vec
<&str> = data
.splitn(4, |c
: char| c
== 'ä'
).collect();
943 assert_eq
!(split
, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
947 fn test_split_char_iterator_no_trailing() {
948 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
950 let split
: Vec
<&str> = data
.split('
\n'
).collect();
951 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb", ""]);
953 let split
: Vec
<&str> = data
.split_terminator('
\n'
).collect();
954 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb"]);
959 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
961 let split
: Vec
<&str> = data
.rsplit(' '
).collect();
962 assert_eq
!(split
, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
964 let split
: Vec
<&str> = data
.rsplit("lämb").collect();
965 assert_eq
!(split
, ["\n", "\nLittle ", "\nMäry häd ä little "]);
967 let split
: Vec
<&str> = data
.rsplit(|c
: char| c
== 'ä'
).collect();
968 assert_eq
!(split
, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
973 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
975 let split
: Vec
<&str> = data
.rsplitn(2, ' '
).collect();
976 assert_eq
!(split
, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
978 let split
: Vec
<&str> = data
.rsplitn(2, "lämb").collect();
979 assert_eq
!(split
, ["\n", "\nMäry häd ä little lämb\nLittle "]);
981 let split
: Vec
<&str> = data
.rsplitn(2, |c
: char| c
== 'ä'
).collect();
982 assert_eq
!(split
, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
986 fn test_split_whitespace() {
987 let data
= "\n \tMäry häd\tä little lämb\nLittle lämb\n";
988 let words
: Vec
<&str> = data
.split_whitespace().collect();
989 assert_eq
!(words
, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
994 let data
= "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
995 let lines
: Vec
<&str> = data
.lines().collect();
996 assert_eq
!(lines
, ["", "Märy häd ä little lämb", "", "Little lämb"]);
998 let data
= "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
999 let lines
: Vec
<&str> = data
.lines().collect();
1000 assert_eq
!(lines
, ["", "Märy häd ä little lämb", "", "Little lämb"]);
1004 fn test_splitator() {
1005 fn t(s
: &str, sep
: &str, u
: &[&str]) {
1006 let v
: Vec
<&str> = s
.split(sep
).collect();
1009 t("--1233345--", "12345", &["--1233345--"]);
1010 t("abc::hello::there", "::", &["abc", "hello", "there"]);
1011 t("::hello::there", "::", &["", "hello", "there"]);
1012 t("hello::there::", "::", &["hello", "there", ""]);
1013 t("::hello::there::", "::", &["", "hello", "there", ""]);
1014 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
1015 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
1016 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
1017 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
1019 t("zz", "zz", &["",""]);
1020 t("ok", "z", &["ok"]);
1021 t("zzz", "zz", &["","z"]);
1022 t("zzzzz", "zz", &["","","z"]);
1026 fn test_str_default() {
1027 use std
::default::Default
;
1029 fn t
<S
: Default
+ AsRef
<str>>() {
1030 let s
: S
= Default
::default();
1031 assert_eq
!(s
.as_ref(), "");
1039 fn test_str_container() {
1040 fn sum_len(v
: &[&str]) -> usize {
1041 v
.iter().map(|x
| x
.len()).sum()
1045 assert_eq
!(5, sum_len(&["012", "", "34"]));
1046 assert_eq
!(5, sum_len(&["01", "2", "34", ""]));
1047 assert_eq
!(5, sum_len(&[s
]));
1051 fn test_str_from_utf8() {
1053 assert_eq
!(from_utf8(xs
), Ok("hello"));
1055 let xs
= "ศไทย中华Việt Nam".as_bytes();
1056 assert_eq
!(from_utf8(xs
), Ok("ศไทย中华Việt Nam"));
1058 let xs
= b
"hello\xFF";
1059 assert
!(from_utf8(xs
).is_err());
1063 fn test_pattern_deref_forward() {
1064 let data
= "aabcdaa";
1065 assert
!(data
.contains("bcd"));
1066 assert
!(data
.contains(&"bcd"));
1067 assert
!(data
.contains(&"bcd".to_string()));
1071 fn test_empty_match_indices() {
1073 let vec
: Vec
<_
> = data
.match_indices("").collect();
1074 assert_eq
!(vec
, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1078 fn test_bool_from_str() {
1079 assert_eq
!("true".parse().ok(), Some(true));
1080 assert_eq
!("false".parse().ok(), Some(false));
1081 assert_eq
!("not even a boolean".parse
::<bool
>().ok(), None
);
1084 fn check_contains_all_substrings(s
: &str) {
1085 assert
!(s
.contains(""));
1086 for i
in 0..s
.len() {
1087 for j
in i
+1..s
.len() + 1 {
1088 assert
!(s
.contains(&s
[i
..j
]));
1094 fn strslice_issue_16589() {
1095 assert
!("bananas".contains("nana"));
1097 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1098 // test all substrings for good measure
1099 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1103 fn strslice_issue_16878() {
1104 assert
!(!"1234567ah012345678901ah".contains("hah"));
1105 assert
!(!"00abc01234567890123456789abc".contains("bcabc"));
1110 fn test_strslice_contains() {
1111 let x
= "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1112 check_contains_all_substrings(x
);
1116 fn test_rsplitn_char_iterator() {
1117 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1119 let mut split
: Vec
<&str> = data
.rsplitn(4, ' '
).collect();
1121 assert_eq
!(split
, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1123 let mut split
: Vec
<&str> = data
.rsplitn(4, |c
: char| c
== ' '
).collect();
1125 assert_eq
!(split
, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1128 let mut split
: Vec
<&str> = data
.rsplitn(4, 'ä'
).collect();
1130 assert_eq
!(split
, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1132 let mut split
: Vec
<&str> = data
.rsplitn(4, |c
: char| c
== 'ä'
).collect();
1134 assert_eq
!(split
, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1138 fn test_split_char_iterator() {
1139 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1141 let split
: Vec
<&str> = data
.split(' '
).collect();
1142 assert_eq
!( split
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1144 let mut rsplit
: Vec
<&str> = data
.split(' '
).rev().collect();
1146 assert_eq
!(rsplit
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1148 let split
: Vec
<&str> = data
.split(|c
: char| c
== ' '
).collect();
1149 assert_eq
!( split
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1151 let mut rsplit
: Vec
<&str> = data
.split(|c
: char| c
== ' '
).rev().collect();
1153 assert_eq
!(rsplit
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1156 let split
: Vec
<&str> = data
.split('ä'
).collect();
1157 assert_eq
!( split
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1159 let mut rsplit
: Vec
<&str> = data
.split('ä'
).rev().collect();
1161 assert_eq
!(rsplit
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1163 let split
: Vec
<&str> = data
.split(|c
: char| c
== 'ä'
).collect();
1164 assert_eq
!( split
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1166 let mut rsplit
: Vec
<&str> = data
.split(|c
: char| c
== 'ä'
).rev().collect();
1168 assert_eq
!(rsplit
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1172 fn test_rev_split_char_iterator_no_trailing() {
1173 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1175 let mut split
: Vec
<&str> = data
.split('
\n'
).rev().collect();
1177 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1179 let mut split
: Vec
<&str> = data
.split_terminator('
\n'
).rev().collect();
1181 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb"]);
1185 fn test_utf16_code_units() {
1186 use rustc_unicode
::str::Utf16Encoder
;
1187 assert_eq
!(Utf16Encoder
::new(vec
!['é'
, '
\u{1F4A9}'
].into_iter()).collect
::<Vec
<u16>>(),
1188 [0xE9, 0xD83D, 0xDCA9])
1192 fn starts_with_in_unicode() {
1193 assert
!(!"├── Cargo.toml".starts_with("# "));
1197 fn starts_short_long() {
1198 assert
!(!"".starts_with("##"));
1199 assert
!(!"##".starts_with("####"));
1200 assert
!("####".starts_with("##"));
1201 assert
!(!"##ä".starts_with("####"));
1202 assert
!("####ä".starts_with("##"));
1203 assert
!(!"##".starts_with("####ä"));
1204 assert
!("##ä##".starts_with("##ä"));
1206 assert
!("".starts_with(""));
1207 assert
!("ä".starts_with(""));
1208 assert
!("#ä".starts_with(""));
1209 assert
!("##ä".starts_with(""));
1210 assert
!("ä###".starts_with(""));
1211 assert
!("#ä##".starts_with(""));
1212 assert
!("##ä#".starts_with(""));
1216 fn contains_weird_cases() {
1217 assert
!("* \t".contains(' '
));
1218 assert
!(!"* \t".contains('?'
));
1219 assert
!(!"* \t".contains('
\u{1F4A9}'
));
1224 assert_eq
!(" \t a \t ".trim_left_matches(|c
: char| c
.is_whitespace()),
1226 assert_eq
!(" \t a \t ".trim_right_matches(|c
: char| c
.is_whitespace()),
1228 assert_eq
!(" \t a \t ".trim_matches(|c
: char| c
.is_whitespace()),
1230 assert_eq
!(" \t \t ".trim_left_matches(|c
: char| c
.is_whitespace()),
1232 assert_eq
!(" \t \t ".trim_right_matches(|c
: char| c
.is_whitespace()),
1234 assert_eq
!(" \t \t ".trim_matches(|c
: char| c
.is_whitespace()),
1240 assert_eq
!("".to_lowercase(), "");
1241 assert_eq
!("AÉDžaé ".to_lowercase(), "aédžaé ");
1243 // https://github.com/rust-lang/rust/issues/26035
1244 assert_eq
!("ΑΣ".to_lowercase(), "ας");
1245 assert_eq
!("Α'Σ".to_lowercase(), "α'ς");
1246 assert_eq
!("Α''Σ".to_lowercase(), "α''ς");
1248 assert_eq
!("ΑΣ Α".to_lowercase(), "ας α");
1249 assert_eq
!("Α'Σ Α".to_lowercase(), "α'ς α");
1250 assert_eq
!("Α''Σ Α".to_lowercase(), "α''ς α");
1252 assert_eq
!("ΑΣ' Α".to_lowercase(), "ας' α");
1253 assert_eq
!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1255 assert_eq
!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1256 assert_eq
!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1258 assert_eq
!("Α Σ".to_lowercase(), "α σ");
1259 assert_eq
!("Α 'Σ".to_lowercase(), "α 'σ");
1260 assert_eq
!("Α ''Σ".to_lowercase(), "α ''σ");
1262 assert_eq
!("Σ".to_lowercase(), "σ");
1263 assert_eq
!("'Σ".to_lowercase(), "'σ");
1264 assert_eq
!("''Σ".to_lowercase(), "''σ");
1266 assert_eq
!("ΑΣΑ".to_lowercase(), "ασα");
1267 assert_eq
!("ΑΣ'Α".to_lowercase(), "ασ'α");
1268 assert_eq
!("ΑΣ''Α".to_lowercase(), "ασ''α");
1273 assert_eq
!("".to_uppercase(), "");
1274 assert_eq
!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1278 fn test_into_string() {
1279 // The only way to acquire a Box<str> in the first place is through a String, so just
1280 // test that we can round-trip between Box<str> and String.
1281 let string
= String
::from("Some text goes here");
1282 assert_eq
!(string
.clone().into_boxed_str().into_string(), string
);
1286 fn test_box_slice_clone() {
1287 let data
= String
::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1288 let data2
= data
.clone().into_boxed_str().clone().into_string();
1290 assert_eq
!(data
, data2
);
1294 fn test_cow_from() {
1295 let borrowed
= "borrowed";
1296 let owned
= String
::from("owned");
1297 match (Cow
::from(owned
.clone()), Cow
::from(borrowed
)) {
1298 (Cow
::Owned(o
), Cow
::Borrowed(b
)) => assert
!(o
== owned
&& b
== borrowed
),
1299 _
=> panic
!("invalid `Cow::from`"),
1304 use std
::str::pattern
::Pattern
;
1305 use std
::str::pattern
::{Searcher, ReverseSearcher}
;
1306 use std
::str::pattern
::SearchStep
::{self, Match, Reject, Done}
;
1308 macro_rules
! make_test
{
1309 ($name
:ident
, $p
:expr
, $h
:expr
, [$
($e
:expr
,)*]) => {
1310 #[allow(unused_imports)]
1312 use std
::str::pattern
::SearchStep
::{Match, Reject}
;
1313 use super::{cmp_search_to_vec}
;
1316 cmp_search_to_vec(false, $p
, $h
, vec
![$
($e
),*]);
1320 cmp_search_to_vec(true, $p
, $h
, vec
![$
($e
),*]);
1326 fn cmp_search_to_vec
<'a
, P
: Pattern
<'a
>>(rev
: bool
, pat
: P
, haystack
: &'a
str,
1327 right
: Vec
<SearchStep
>)
1328 where P
::Searcher
: ReverseSearcher
<'a
>
1330 let mut searcher
= pat
.into_searcher(haystack
);
1333 match if !rev {searcher.next()}
else {searcher.next_back()}
{
1334 Match(a
, b
) => v
.push(Match(a
, b
)),
1335 Reject(a
, b
) => v
.push(Reject(a
, b
)),
1343 let mut first_index
= 0;
1346 for (i
, e
) in right
.iter().enumerate() {
1348 Match(a
, b
) | Reject(a
, b
)
1349 if a
<= b
&& a
== first_index
=> {
1359 if let Some(err
) = err
{
1360 panic
!("Input skipped range at {}", err
);
1363 if first_index
!= haystack
.len() {
1364 panic
!("Did not cover whole input");
1367 assert_eq
!(v
, right
);
1370 make_test
!(str_searcher_ascii_haystack
, "bb", "abbcbbd", [
1377 make_test
!(str_searcher_ascii_haystack_seq
, "bb", "abbcbbbbd", [
1385 make_test
!(str_searcher_empty_needle_ascii_haystack
, "", "abbcbbd", [
1402 make_test
!(str_searcher_mulibyte_haystack
, " ", "├──", [
1407 make_test
!(str_searcher_empty_needle_mulibyte_haystack
, "", "├──", [
1416 make_test
!(str_searcher_empty_needle_empty_haystack
, "", "", [
1419 make_test
!(str_searcher_nonempty_needle_empty_haystack
, "├", "", [
1421 make_test
!(char_searcher_ascii_haystack
, 'b'
, "abbcbbd", [
1430 make_test
!(char_searcher_mulibyte_haystack
, ' '
, "├──", [
1435 make_test
!(char_searcher_short_haystack
, '
\u{1F4A9}'
, "* \t", [
1443 macro_rules
! generate_iterator_test
{
1447 ($
($arg
:expr
),*) -> [$
($t
:tt
)*];
1450 with $fwd
:expr
, $bwd
:expr
;
1456 let res
= vec
![$
($t
)*];
1458 let fwd_vec
: Vec
<_
> = ($fwd
)($
($arg
),*).collect();
1459 assert_eq
!(fwd_vec
, res
);
1461 let mut bwd_vec
: Vec
<_
> = ($bwd
)($
($arg
),*).collect();
1463 assert_eq
!(bwd_vec
, res
);
1471 ($
($arg
:expr
),*) -> [$
($t
:tt
)*];
1480 let res
= vec
![$
($t
)*];
1482 let fwd_vec
: Vec
<_
> = ($fwd
)($
($arg
),*).collect();
1483 assert_eq
!(fwd_vec
, res
);
1490 generate_iterator_test
! {
1491 double_ended_split
{
1492 ("foo.bar.baz", '
.'
) -> ["foo", "bar", "baz"];
1493 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1495 with
str::split
, str::rsplit
;
1498 generate_iterator_test
! {
1499 double_ended_split_terminator
{
1500 ("foo;bar;baz;", '
;'
) -> ["foo", "bar", "baz"];
1502 with
str::split_terminator
, str::rsplit_terminator
;
1505 generate_iterator_test
! {
1506 double_ended_matches
{
1507 ("a1b2c3", char::is_numeric
) -> ["1", "2", "3"];
1509 with
str::matches
, str::rmatches
;
1512 generate_iterator_test
! {
1513 double_ended_match_indices
{
1514 ("a1b2c3", char::is_numeric
) -> [(1, "1"), (3, "2"), (5, "3")];
1516 with
str::match_indices
, str::rmatch_indices
;
1519 generate_iterator_test
! {
1520 not_double_ended_splitn
{
1521 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1526 generate_iterator_test
! {
1527 not_double_ended_rsplitn
{
1528 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1534 fn different_str_pattern_forwarding_lifetimes() {
1535 use std
::str::pattern
::Pattern
;
1537 fn foo
<'a
, P
>(p
: P
) where for<'b
> &'b P
: Pattern
<'a
> {
1547 use test
::{Bencher, black_box}
;
1550 fn char_iterator(b
: &mut Bencher
) {
1551 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1553 b
.iter(|| s
.chars().count());
1557 fn char_iterator_for(b
: &mut Bencher
) {
1558 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1561 for ch
in s
.chars() { black_box(ch); }
1566 fn char_iterator_ascii(b
: &mut Bencher
) {
1567 let s
= "Mary had a little lamb, Little lamb
1568 Mary had a little lamb, Little lamb
1569 Mary had a little lamb, Little lamb
1570 Mary had a little lamb, Little lamb
1571 Mary had a little lamb, Little lamb
1572 Mary had a little lamb, Little lamb";
1574 b
.iter(|| s
.chars().count());
1578 fn char_iterator_rev(b
: &mut Bencher
) {
1579 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1581 b
.iter(|| s
.chars().rev().count());
1585 fn char_iterator_rev_for(b
: &mut Bencher
) {
1586 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1589 for ch
in s
.chars().rev() { black_box(ch); }
1594 fn char_indicesator(b
: &mut Bencher
) {
1595 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1596 let len
= s
.chars().count();
1598 b
.iter(|| assert_eq
!(s
.char_indices().count(), len
));
1602 fn char_indicesator_rev(b
: &mut Bencher
) {
1603 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1604 let len
= s
.chars().count();
1606 b
.iter(|| assert_eq
!(s
.char_indices().rev().count(), len
));
1610 fn split_unicode_ascii(b
: &mut Bencher
) {
1611 let s
= "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
1613 b
.iter(|| assert_eq
!(s
.split('V'
).count(), 3));
1617 fn split_ascii(b
: &mut Bencher
) {
1618 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1619 let len
= s
.split(' '
).count();
1621 b
.iter(|| assert_eq
!(s
.split(' '
).count(), len
));
1625 fn split_extern_fn(b
: &mut Bencher
) {
1626 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1627 let len
= s
.split(' '
).count();
1628 fn pred(c
: char) -> bool { c == ' ' }
1630 b
.iter(|| assert_eq
!(s
.split(pred
).count(), len
));
1634 fn split_closure(b
: &mut Bencher
) {
1635 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1636 let len
= s
.split(' '
).count();
1638 b
.iter(|| assert_eq
!(s
.split(|c
: char| c
== ' '
).count(), len
));
1642 fn split_slice(b
: &mut Bencher
) {
1643 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1644 let len
= s
.split(' '
).count();
1646 let c
: &[char] = &[' '
];
1647 b
.iter(|| assert_eq
!(s
.split(c
).count(), len
));
1651 fn bench_join(b
: &mut Bencher
) {
1652 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1654 let v
= vec
![s
, s
, s
, s
, s
, s
, s
, s
, s
, s
];
1656 assert_eq
!(v
.join(sep
).len(), s
.len() * 10 + sep
.len() * 9);
1661 fn bench_contains_short_short(b
: &mut Bencher
) {
1662 let haystack
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1666 assert
!(haystack
.contains(needle
));
1671 fn bench_contains_short_long(b
: &mut Bencher
) {
1673 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1674 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1675 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1676 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1677 tempus vel, gravida nec quam.
1679 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1680 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1681 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1682 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1683 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1684 interdum. Curabitur ut nisi justo.
1686 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1687 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1688 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1689 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1690 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1691 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1692 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1693 Aliquam sit amet placerat lorem.
1695 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1696 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1697 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1698 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1699 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1702 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1703 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1704 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1705 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1706 malesuada sollicitudin quam eu fermentum.";
1707 let needle
= "english";
1710 assert
!(!haystack
.contains(needle
));
1715 fn bench_contains_bad_naive(b
: &mut Bencher
) {
1716 let haystack
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1717 let needle
= "aaaaaaaab";
1720 assert
!(!haystack
.contains(needle
));
1725 fn bench_contains_equal(b
: &mut Bencher
) {
1726 let haystack
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1727 let needle
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1730 assert
!(haystack
.contains(needle
));
1734 macro_rules
! make_test_inner
{
1735 ($s
:ident
, $code
:expr
, $name
:ident
, $
str:expr
) => {
1737 fn $
name(bencher
: &mut Bencher
) {
1740 bencher
.iter(|| $code
);
1745 macro_rules
! make_test
{
1746 ($name
:ident
, $s
:ident
, $code
:expr
) => {
1749 use test
::black_box
;
1751 // Short strings: 65 bytes each
1752 make_test_inner
!($s
, $code
, short_ascii
,
1753 "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
1754 make_test_inner
!($s
, $code
, short_mixed
,
1755 "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
1756 make_test_inner
!($s
, $code
, short_pile_of_poo
,
1757 "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
1758 make_test_inner
!($s
, $code
, long_lorem_ipsum
,"\
1759 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1760 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1761 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1762 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1763 tempus vel, gravida nec quam.
1765 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1766 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1767 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1768 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1769 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1770 interdum. Curabitur ut nisi justo.
1772 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1773 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1774 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1775 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1776 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1777 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1778 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1779 Aliquam sit amet placerat lorem.
1781 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1782 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1783 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1784 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1785 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1788 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1789 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1790 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1791 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1792 malesuada sollicitudin quam eu fermentum!");
1797 make_test
!(chars_count
, s
, s
.chars().count());
1799 make_test
!(contains_bang_str
, s
, s
.contains("!"));
1800 make_test
!(contains_bang_char
, s
, s
.contains('
!'
));
1802 make_test
!(match_indices_a_str
, s
, s
.match_indices("a").count());
1804 make_test
!(split_a_str
, s
, s
.split("a").count());
1806 make_test
!(trim_ascii_char
, s
, {
1807 use std
::ascii
::AsciiExt
;
1808 s
.trim_matches(|c
: char| c
.is_ascii())
1810 make_test
!(trim_left_ascii_char
, s
, {
1811 use std
::ascii
::AsciiExt
;
1812 s
.trim_left_matches(|c
: char| c
.is_ascii())
1814 make_test
!(trim_right_ascii_char
, s
, {
1815 use std
::ascii
::AsciiExt
;
1816 s
.trim_right_matches(|c
: char| c
.is_ascii())
1819 make_test
!(find_underscore_char
, s
, s
.find('_'
));
1820 make_test
!(rfind_underscore_char
, s
, s
.rfind('_'
));
1821 make_test
!(find_underscore_str
, s
, s
.find("_"));
1823 make_test
!(find_zzz_char
, s
, s
.find('
\u{1F4A4}'
));
1824 make_test
!(rfind_zzz_char
, s
, s
.rfind('
\u{1F4A4}'
));
1825 make_test
!(find_zzz_str
, s
, s
.find("\u{1F4A4}"));
1827 make_test
!(split_space_char
, s
, s
.split(' '
).count());
1828 make_test
!(split_terminator_space_char
, s
, s
.split_terminator(' '
).count());
1830 make_test
!(splitn_space_char
, s
, s
.splitn(10, ' '
).count());
1831 make_test
!(rsplitn_space_char
, s
, s
.rsplitn(10, ' '
).count());
1833 make_test
!(split_space_str
, s
, s
.split(" ").count());
1834 make_test
!(split_ad_str
, s
, s
.split("ad").count());