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"]);
129 fn test_concat_for_different_lengths() {
130 let empty
: &[&str] = &[];
131 test_concat
!("", empty
);
132 test_concat
!("a", ["a"]);
133 test_concat
!("ab", ["a", "b"]);
134 test_concat
!("abc", ["", "a", "bc"]);
137 macro_rules
! test_join
{
138 ($expected
: expr
, $string
: expr
, $delim
: expr
) => {
140 let s
= $string
.join($delim
);
141 assert_eq
!($expected
, s
);
147 fn test_join_for_different_types() {
148 test_join
!("a-b", ["a", "b"], "-");
149 let hyphen
= "-".to_string();
150 test_join
!("a-b", [s("a"), s("b")], &*hyphen
);
151 test_join
!("a-b", vec
!["a", "b"], &*hyphen
);
152 test_join
!("a-b", &*vec
!["a", "b"], "-");
153 test_join
!("a-b", vec
![s("a"), s("b")], "-");
157 fn test_join_for_different_lengths() {
158 let empty
: &[&str] = &[];
159 test_join
!("", empty
, "-");
160 test_join
!("a", ["a"], "-");
161 test_join
!("a-b", ["a", "b"], "-");
162 test_join
!("-a-bc", ["", "a", "bc"], "-");
166 fn test_unsafe_slice() {
167 assert_eq
!("ab", unsafe {"abc".slice_unchecked(0, 2)}
);
168 assert_eq
!("bc", unsafe {"abc".slice_unchecked(1, 3)}
);
169 assert_eq
!("", unsafe {"abc".slice_unchecked(1, 1)}
);
170 fn a_million_letter_a() -> String
{
172 let mut rs
= String
::new();
174 rs
.push_str("aaaaaaaaaa");
179 fn half_a_million_letter_a() -> String
{
181 let mut rs
= String
::new();
183 rs
.push_str("aaaaa");
188 let letters
= a_million_letter_a();
189 assert_eq
!(half_a_million_letter_a(),
190 unsafe { letters.slice_unchecked(0, 500000)}
);
194 fn test_starts_with() {
195 assert
!("".starts_with(""));
196 assert
!("abc".starts_with(""));
197 assert
!("abc".starts_with("a"));
198 assert
!(!"a".starts_with("abc"));
199 assert
!(!"".starts_with("abc"));
200 assert
!(!"ödd".starts_with("-"));
201 assert
!("ödd".starts_with("öd"));
205 fn test_ends_with() {
206 assert
!("".ends_with(""));
207 assert
!("abc".ends_with(""));
208 assert
!("abc".ends_with("c"));
209 assert
!(!"a".ends_with("abc"));
210 assert
!(!"".ends_with("abc"));
211 assert
!(!"ddö".ends_with("-"));
212 assert
!("ddö".ends_with("dö"));
217 assert
!("".is_empty());
218 assert
!(!"a".is_empty());
224 assert_eq
!("".replace(a
, "b"), "");
225 assert_eq
!("a".replace(a
, "b"), "b");
226 assert_eq
!("ab".replace(a
, "b"), "bb");
228 assert_eq
!(" test test ".replace(test
, "toast"), " toast toast ");
229 assert_eq
!(" test test ".replace(test
, ""), " ");
233 fn test_replace_2a() {
234 let data
= "ประเทศไทย中华";
235 let repl
= "دولة الكويت";
238 let a2
= "دولة الكويتทศไทย中华";
239 assert_eq
!(data
.replace(a
, repl
), a2
);
243 fn test_replace_2b() {
244 let data
= "ประเทศไทย中华";
245 let repl
= "دولة الكويت";
248 let b2
= "ปรدولة الكويتทศไทย中华";
249 assert_eq
!(data
.replace(b
, repl
), b2
);
253 fn test_replace_2c() {
254 let data
= "ประเทศไทย中华";
255 let repl
= "دولة الكويت";
258 let c2
= "ประเทศไทยدولة الكويت";
259 assert_eq
!(data
.replace(c
, repl
), c2
);
263 fn test_replace_2d() {
264 let data
= "ประเทศไทย中华";
265 let repl
= "دولة الكويت";
268 assert_eq
!(data
.replace(d
, repl
), data
);
272 fn test_replace_pattern() {
273 let data
= "abcdαβγδabcdαβγδ";
274 assert_eq
!(data
.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
275 assert_eq
!(data
.replace('γ'
, "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
276 assert_eq
!(data
.replace(&['a'
, 'γ'
] as &[_
], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
277 assert_eq
!(data
.replace(|c
| c
== 'γ'
, "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
282 assert_eq
!("ab", &"abc"[0..2]);
283 assert_eq
!("bc", &"abc"[1..3]);
284 assert_eq
!("", &"abc"[1..1]);
285 assert_eq
!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
287 let data
= "ประเทศไทย中华";
288 assert_eq
!("ป", &data
[0..3]);
289 assert_eq
!("ร", &data
[3..6]);
290 assert_eq
!("", &data
[3..3]);
291 assert_eq
!("华", &data
[30..33]);
293 fn a_million_letter_x() -> String
{
295 let mut rs
= String
::new();
297 rs
.push_str("华华华华华华华华华华");
302 fn half_a_million_letter_x() -> String
{
304 let mut rs
= String
::new();
306 rs
.push_str("华华华华华");
311 let letters
= a_million_letter_x();
312 assert_eq
!(half_a_million_letter_x(), &letters
[0..3 * 500000]);
317 let ss
= "中华Việt Nam";
319 assert_eq
!("华", &ss
[3..6]);
320 assert_eq
!("Việt Nam", &ss
[6..16]);
322 assert_eq
!("ab", &"abc"[0..2]);
323 assert_eq
!("bc", &"abc"[1..3]);
324 assert_eq
!("", &"abc"[1..1]);
326 assert_eq
!("中", &ss
[0..3]);
327 assert_eq
!("华V", &ss
[3..7]);
328 assert_eq
!("", &ss
[3..3]);
343 fn test_slice_fail() {
349 fn test_is_char_boundary() {
350 let s
= "ศไทย中华Việt Nam β-release 🐱123";
351 assert
!(s
.is_char_boundary(0));
352 assert
!(s
.is_char_boundary(s
.len()));
353 assert
!(!s
.is_char_boundary(s
.len() + 1));
354 for (i
, ch
) in s
.char_indices() {
355 // ensure character locations are boundaries and continuation bytes are not
356 assert
!(s
.is_char_boundary(i
), "{} is a char boundary in {:?}", i
, s
);
357 for j
in 1..ch
.len_utf8() {
358 assert
!(!s
.is_char_boundary(i
+ j
),
359 "{} should not be a char boundary in {:?}", i
+ j
, s
);
363 const LOREM_PARAGRAPH
: &'
static str = "\
364 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
365 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
366 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
367 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
368 tempus vel, gravida nec quam.";
370 // check the panic includes the prefix of the sliced string
372 #[should_panic(expected="Lorem ipsum dolor sit amet")]
373 fn test_slice_fail_truncated_1() {
374 &LOREM_PARAGRAPH
[..1024];
376 // check the truncation in the panic message
378 #[should_panic(expected="luctus, im`[...] do not lie on character boundary")]
379 fn test_slice_fail_truncated_2() {
380 &LOREM_PARAGRAPH
[..1024];
384 fn test_slice_from() {
385 assert_eq
!(&"abcd"[0..], "abcd");
386 assert_eq
!(&"abcd"[2..], "cd");
387 assert_eq
!(&"abcd"[4..], "");
391 assert_eq
!(&"abcd"[..0], "");
392 assert_eq
!(&"abcd"[..2], "ab");
393 assert_eq
!(&"abcd"[..4], "abcd");
397 fn test_trim_left_matches() {
398 let v
: &[char] = &[];
399 assert_eq
!(" *** foo *** ".trim_left_matches(v
), " *** foo *** ");
400 let chars
: &[char] = &['
*'
, ' '
];
401 assert_eq
!(" *** foo *** ".trim_left_matches(chars
), "foo *** ");
402 assert_eq
!(" *** *** ".trim_left_matches(chars
), "");
403 assert_eq
!("foo *** ".trim_left_matches(chars
), "foo *** ");
405 assert_eq
!("11foo1bar11".trim_left_matches('
1'
), "foo1bar11");
406 let chars
: &[char] = &['
1'
, '
2'
];
407 assert_eq
!("12foo1bar12".trim_left_matches(chars
), "foo1bar12");
408 assert_eq
!("123foo1bar123".trim_left_matches(|c
: char| c
.is_numeric()), "foo1bar123");
412 fn test_trim_right_matches() {
413 let v
: &[char] = &[];
414 assert_eq
!(" *** foo *** ".trim_right_matches(v
), " *** foo *** ");
415 let chars
: &[char] = &['
*'
, ' '
];
416 assert_eq
!(" *** foo *** ".trim_right_matches(chars
), " *** foo");
417 assert_eq
!(" *** *** ".trim_right_matches(chars
), "");
418 assert_eq
!(" *** foo".trim_right_matches(chars
), " *** foo");
420 assert_eq
!("11foo1bar11".trim_right_matches('
1'
), "11foo1bar");
421 let chars
: &[char] = &['
1'
, '
2'
];
422 assert_eq
!("12foo1bar12".trim_right_matches(chars
), "12foo1bar");
423 assert_eq
!("123foo1bar123".trim_right_matches(|c
: char| c
.is_numeric()), "123foo1bar");
427 fn test_trim_matches() {
428 let v
: &[char] = &[];
429 assert_eq
!(" *** foo *** ".trim_matches(v
), " *** foo *** ");
430 let chars
: &[char] = &['
*'
, ' '
];
431 assert_eq
!(" *** foo *** ".trim_matches(chars
), "foo");
432 assert_eq
!(" *** *** ".trim_matches(chars
), "");
433 assert_eq
!("foo".trim_matches(chars
), "foo");
435 assert_eq
!("11foo1bar11".trim_matches('
1'
), "foo1bar");
436 let chars
: &[char] = &['
1'
, '
2'
];
437 assert_eq
!("12foo1bar12".trim_matches(chars
), "foo1bar");
438 assert_eq
!("123foo1bar123".trim_matches(|c
: char| c
.is_numeric()), "foo1bar");
442 fn test_trim_left() {
443 assert_eq
!("".trim_left(), "");
444 assert_eq
!("a".trim_left(), "a");
445 assert_eq
!(" ".trim_left(), "");
446 assert_eq
!(" blah".trim_left(), "blah");
447 assert_eq
!(" \u{3000} wut".trim_left(), "wut");
448 assert_eq
!("hey ".trim_left(), "hey ");
452 fn test_trim_right() {
453 assert_eq
!("".trim_right(), "");
454 assert_eq
!("a".trim_right(), "a");
455 assert_eq
!(" ".trim_right(), "");
456 assert_eq
!("blah ".trim_right(), "blah");
457 assert_eq
!("wut \u{3000} ".trim_right(), "wut");
458 assert_eq
!(" hey".trim_right(), " hey");
463 assert_eq
!("".trim(), "");
464 assert_eq
!("a".trim(), "a");
465 assert_eq
!(" ".trim(), "");
466 assert_eq
!(" blah ".trim(), "blah");
467 assert_eq
!("\nwut \u{3000} ".trim(), "wut");
468 assert_eq
!(" hey dude ".trim(), "hey dude");
472 fn test_is_whitespace() {
473 assert
!("".chars().all(|c
| c
.is_whitespace()));
474 assert
!(" ".chars().all(|c
| c
.is_whitespace()));
475 assert
!("\u{2009}".chars().all(|c
| c
.is_whitespace())); // Thin space
476 assert
!(" \n\t ".chars().all(|c
| c
.is_whitespace()));
477 assert
!(!" _ ".chars().all(|c
| c
.is_whitespace()));
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'
));
663 let s
= "ศไทย中华Việt Nam";
664 for (index
, _
) in s
.char_indices() {
665 let (a
, b
) = s
.split_at(index
);
666 assert_eq
!(&s
[..a
.len()], a
);
667 assert_eq
!(&s
[a
.len()..], b
);
669 let (a
, b
) = s
.split_at(s
.len());
675 fn test_split_at_mut() {
676 use std
::ascii
::AsciiExt
;
677 let mut s
= "Hello World".to_string();
679 let (a
, b
) = s
.split_at_mut(5);
680 a
.make_ascii_uppercase();
681 b
.make_ascii_lowercase();
683 assert_eq
!(s
, "HELLO world");
688 fn test_split_at_boundscheck() {
689 let s
= "ศไทย中华Việt Nam";
694 fn test_escape_unicode() {
695 assert_eq
!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
696 assert_eq
!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
697 assert_eq
!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
698 assert_eq
!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
699 assert_eq
!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
700 assert_eq
!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
701 assert_eq
!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
702 assert_eq
!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
703 assert_eq
!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
707 fn test_escape_debug() {
708 assert_eq
!("abc".escape_debug(), "abc");
709 assert_eq
!("a c".escape_debug(), "a c");
710 assert_eq
!("éèê".escape_debug(), "éèê");
711 assert_eq
!("\r\n\t".escape_debug(), "\\r\\n\\t");
712 assert_eq
!("'\"\\".escape_debug(), "\\'\\\"\\\\");
713 assert_eq
!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
714 assert_eq
!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
715 assert_eq
!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
716 assert_eq
!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
717 assert_eq
!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
721 fn test_escape_default() {
722 assert_eq
!("abc".escape_default(), "abc");
723 assert_eq
!("a c".escape_default(), "a c");
724 assert_eq
!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
725 assert_eq
!("\r\n\t".escape_default(), "\\r\\n\\t");
726 assert_eq
!("'\"\\".escape_default(), "\\'\\\"\\\\");
727 assert_eq
!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
728 assert_eq
!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
729 assert_eq
!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
730 assert_eq
!("ab\u{200b}".escape_default(), "ab\\u{200b}");
731 assert_eq
!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
735 fn test_total_ord() {
736 assert_eq
!("1234".cmp("123"), Greater
);
737 assert_eq
!("123".cmp("1234"), Less
);
738 assert_eq
!("1234".cmp("1234"), Equal
);
739 assert_eq
!("12345555".cmp("123456"), Less
);
740 assert_eq
!("22".cmp("1234"), Greater
);
745 let s
= "ศไทย中华Việt Nam";
746 let v
= ['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
752 assert_eq
!(c
, v
[pos
]);
755 assert_eq
!(pos
, v
.len());
759 fn test_rev_iterator() {
760 let s
= "ศไทย中华Việt Nam";
761 let v
= ['m'
, 'a'
, 'N'
, ' '
, 't'
, 'ệ'
,'i'
,'V'
,'华'
,'中'
,'ย'
,'ท'
,'ไ'
,'ศ'
];
764 let it
= s
.chars().rev();
767 assert_eq
!(c
, v
[pos
]);
770 assert_eq
!(pos
, v
.len());
774 fn test_chars_decoding() {
775 for c
in (0..0x110000).filter_map(::std
::char::from_u32
) {
776 let bytes
= c
.encode_utf8();
777 let s
= ::std
::str::from_utf8(bytes
.as_slice()).unwrap();
778 if Some(c
) != s
.chars().next() {
779 panic
!("character {:x}={} does not decode correctly", c
as u32, c
);
785 fn test_chars_rev_decoding() {
786 for c
in (0..0x110000).filter_map(::std
::char::from_u32
) {
787 let bytes
= c
.encode_utf8();
788 let s
= ::std
::str::from_utf8(bytes
.as_slice()).unwrap();
789 if Some(c
) != s
.chars().rev().next() {
790 panic
!("character {:x}={} does not decode correctly", c
as u32, c
);
796 fn test_iterator_clone() {
797 let s
= "ศไทย中华Việt Nam";
798 let mut it
= s
.chars();
800 assert
!(it
.clone().zip(it
).all(|(x
,y
)| x
== y
));
804 fn test_bytesator() {
805 let s
= "ศไทย中华Việt Nam";
807 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
808 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
814 assert_eq
!(b
, v
[pos
]);
820 fn test_bytes_revator() {
821 let s
= "ศไทย中华Việt Nam";
823 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
824 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
827 let mut pos
= v
.len();
829 for b
in s
.bytes().rev() {
831 assert_eq
!(b
, v
[pos
]);
836 fn test_bytesator_nth() {
837 let s
= "ศไทย中华Việt Nam";
839 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
840 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
844 let mut b
= s
.bytes();
845 assert_eq
!(b
.nth(2).unwrap(), v
[2]);
846 assert_eq
!(b
.nth(10).unwrap(), v
[10]);
847 assert_eq
!(b
.nth(200), None
);
851 fn test_bytesator_count() {
852 let s
= "ศไทย中华Việt Nam";
855 assert_eq
!(b
.count(), 28)
859 fn test_bytesator_last() {
860 let s
= "ศไทย中华Việt Nam";
863 assert_eq
!(b
.last().unwrap(), 109)
867 fn test_char_indicesator() {
868 let s
= "ศไทย中华Việt Nam";
869 let p
= [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
870 let v
= ['ศ'
,'ไ'
,'ท'
,'ย'
,'中'
,'华'
,'V'
,'i'
,'ệ'
,'t'
,' '
,'N'
,'a'
,'m'
];
873 let it
= s
.char_indices();
876 assert_eq
!(c
, (p
[pos
], v
[pos
]));
879 assert_eq
!(pos
, v
.len());
880 assert_eq
!(pos
, p
.len());
884 fn test_char_indices_revator() {
885 let s
= "ศไทย中华Việt Nam";
886 let p
= [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
887 let v
= ['m'
, 'a'
, 'N'
, ' '
, 't'
, 'ệ'
,'i'
,'V'
,'华'
,'中'
,'ย'
,'ท'
,'ไ'
,'ศ'
];
890 let it
= s
.char_indices().rev();
893 assert_eq
!(c
, (p
[pos
], v
[pos
]));
896 assert_eq
!(pos
, v
.len());
897 assert_eq
!(pos
, p
.len());
901 fn test_splitn_char_iterator() {
902 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
904 let split
: Vec
<&str> = data
.splitn(4, ' '
).collect();
905 assert_eq
!(split
, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
907 let split
: Vec
<&str> = data
.splitn(4, |c
: char| c
== ' '
).collect();
908 assert_eq
!(split
, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
911 let split
: Vec
<&str> = data
.splitn(4, 'ä'
).collect();
912 assert_eq
!(split
, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
914 let split
: Vec
<&str> = data
.splitn(4, |c
: char| c
== 'ä'
).collect();
915 assert_eq
!(split
, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
919 fn test_split_char_iterator_no_trailing() {
920 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
922 let split
: Vec
<&str> = data
.split('
\n'
).collect();
923 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb", ""]);
925 let split
: Vec
<&str> = data
.split_terminator('
\n'
).collect();
926 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb"]);
931 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
933 let split
: Vec
<&str> = data
.rsplit(' '
).collect();
934 assert_eq
!(split
, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
936 let split
: Vec
<&str> = data
.rsplit("lämb").collect();
937 assert_eq
!(split
, ["\n", "\nLittle ", "\nMäry häd ä little "]);
939 let split
: Vec
<&str> = data
.rsplit(|c
: char| c
== 'ä'
).collect();
940 assert_eq
!(split
, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
945 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
947 let split
: Vec
<&str> = data
.rsplitn(2, ' '
).collect();
948 assert_eq
!(split
, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
950 let split
: Vec
<&str> = data
.rsplitn(2, "lämb").collect();
951 assert_eq
!(split
, ["\n", "\nMäry häd ä little lämb\nLittle "]);
953 let split
: Vec
<&str> = data
.rsplitn(2, |c
: char| c
== 'ä'
).collect();
954 assert_eq
!(split
, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
958 fn test_split_whitespace() {
959 let data
= "\n \tMäry häd\tä little lämb\nLittle lämb\n";
960 let words
: Vec
<&str> = data
.split_whitespace().collect();
961 assert_eq
!(words
, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
966 let data
= "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
967 let lines
: Vec
<&str> = data
.lines().collect();
968 assert_eq
!(lines
, ["", "Märy häd ä little lämb", "", "Little lämb"]);
970 let data
= "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
971 let lines
: Vec
<&str> = data
.lines().collect();
972 assert_eq
!(lines
, ["", "Märy häd ä little lämb", "", "Little lämb"]);
976 fn test_splitator() {
977 fn t(s
: &str, sep
: &str, u
: &[&str]) {
978 let v
: Vec
<&str> = s
.split(sep
).collect();
981 t("--1233345--", "12345", &["--1233345--"]);
982 t("abc::hello::there", "::", &["abc", "hello", "there"]);
983 t("::hello::there", "::", &["", "hello", "there"]);
984 t("hello::there::", "::", &["hello", "there", ""]);
985 t("::hello::there::", "::", &["", "hello", "there", ""]);
986 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
987 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
988 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
989 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
991 t("zz", "zz", &["",""]);
992 t("ok", "z", &["ok"]);
993 t("zzz", "zz", &["","z"]);
994 t("zzzzz", "zz", &["","","z"]);
998 fn test_str_default() {
999 use std
::default::Default
;
1001 fn t
<S
: Default
+ AsRef
<str>>() {
1002 let s
: S
= Default
::default();
1003 assert_eq
!(s
.as_ref(), "");
1011 fn test_str_container() {
1012 fn sum_len(v
: &[&str]) -> usize {
1013 v
.iter().map(|x
| x
.len()).sum()
1017 assert_eq
!(5, sum_len(&["012", "", "34"]));
1018 assert_eq
!(5, sum_len(&["01", "2", "34", ""]));
1019 assert_eq
!(5, sum_len(&[s
]));
1023 fn test_str_from_utf8() {
1025 assert_eq
!(from_utf8(xs
), Ok("hello"));
1027 let xs
= "ศไทย中华Việt Nam".as_bytes();
1028 assert_eq
!(from_utf8(xs
), Ok("ศไทย中华Việt Nam"));
1030 let xs
= b
"hello\xFF";
1031 assert
!(from_utf8(xs
).is_err());
1035 fn test_pattern_deref_forward() {
1036 let data
= "aabcdaa";
1037 assert
!(data
.contains("bcd"));
1038 assert
!(data
.contains(&"bcd"));
1039 assert
!(data
.contains(&"bcd".to_string()));
1043 fn test_empty_match_indices() {
1045 let vec
: Vec
<_
> = data
.match_indices("").collect();
1046 assert_eq
!(vec
, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1050 fn test_bool_from_str() {
1051 assert_eq
!("true".parse().ok(), Some(true));
1052 assert_eq
!("false".parse().ok(), Some(false));
1053 assert_eq
!("not even a boolean".parse
::<bool
>().ok(), None
);
1056 fn check_contains_all_substrings(s
: &str) {
1057 assert
!(s
.contains(""));
1058 for i
in 0..s
.len() {
1059 for j
in i
+1..s
.len() + 1 {
1060 assert
!(s
.contains(&s
[i
..j
]));
1066 fn strslice_issue_16589() {
1067 assert
!("bananas".contains("nana"));
1069 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1070 // test all substrings for good measure
1071 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1075 fn strslice_issue_16878() {
1076 assert
!(!"1234567ah012345678901ah".contains("hah"));
1077 assert
!(!"00abc01234567890123456789abc".contains("bcabc"));
1082 fn test_strslice_contains() {
1083 let x
= "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1084 check_contains_all_substrings(x
);
1088 fn test_rsplitn_char_iterator() {
1089 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1091 let mut split
: Vec
<&str> = data
.rsplitn(4, ' '
).collect();
1093 assert_eq
!(split
, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1095 let mut split
: Vec
<&str> = data
.rsplitn(4, |c
: char| c
== ' '
).collect();
1097 assert_eq
!(split
, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1100 let mut split
: Vec
<&str> = data
.rsplitn(4, 'ä'
).collect();
1102 assert_eq
!(split
, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1104 let mut split
: Vec
<&str> = data
.rsplitn(4, |c
: char| c
== 'ä'
).collect();
1106 assert_eq
!(split
, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1110 fn test_split_char_iterator() {
1111 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1113 let split
: Vec
<&str> = data
.split(' '
).collect();
1114 assert_eq
!( split
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1116 let mut rsplit
: Vec
<&str> = data
.split(' '
).rev().collect();
1118 assert_eq
!(rsplit
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1120 let split
: Vec
<&str> = data
.split(|c
: char| c
== ' '
).collect();
1121 assert_eq
!( split
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1123 let mut rsplit
: Vec
<&str> = data
.split(|c
: char| c
== ' '
).rev().collect();
1125 assert_eq
!(rsplit
, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1128 let split
: Vec
<&str> = data
.split('ä'
).collect();
1129 assert_eq
!( split
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1131 let mut rsplit
: Vec
<&str> = data
.split('ä'
).rev().collect();
1133 assert_eq
!(rsplit
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1135 let split
: Vec
<&str> = data
.split(|c
: char| c
== 'ä'
).collect();
1136 assert_eq
!( split
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1138 let mut rsplit
: Vec
<&str> = data
.split(|c
: char| c
== 'ä'
).rev().collect();
1140 assert_eq
!(rsplit
, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1144 fn test_rev_split_char_iterator_no_trailing() {
1145 let data
= "\nMäry häd ä little lämb\nLittle lämb\n";
1147 let mut split
: Vec
<&str> = data
.split('
\n'
).rev().collect();
1149 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1151 let mut split
: Vec
<&str> = data
.split_terminator('
\n'
).rev().collect();
1153 assert_eq
!(split
, ["", "Märy häd ä little lämb", "Little lämb"]);
1157 fn test_utf16_code_units() {
1158 use rustc_unicode
::str::Utf16Encoder
;
1159 assert_eq
!(Utf16Encoder
::new(vec
!['é'
, '
\u{1F4A9}'
].into_iter()).collect
::<Vec
<u16>>(),
1160 [0xE9, 0xD83D, 0xDCA9])
1164 fn starts_with_in_unicode() {
1165 assert
!(!"├── Cargo.toml".starts_with("# "));
1169 fn starts_short_long() {
1170 assert
!(!"".starts_with("##"));
1171 assert
!(!"##".starts_with("####"));
1172 assert
!("####".starts_with("##"));
1173 assert
!(!"##ä".starts_with("####"));
1174 assert
!("####ä".starts_with("##"));
1175 assert
!(!"##".starts_with("####ä"));
1176 assert
!("##ä##".starts_with("##ä"));
1178 assert
!("".starts_with(""));
1179 assert
!("ä".starts_with(""));
1180 assert
!("#ä".starts_with(""));
1181 assert
!("##ä".starts_with(""));
1182 assert
!("ä###".starts_with(""));
1183 assert
!("#ä##".starts_with(""));
1184 assert
!("##ä#".starts_with(""));
1188 fn contains_weird_cases() {
1189 assert
!("* \t".contains(' '
));
1190 assert
!(!"* \t".contains('?'
));
1191 assert
!(!"* \t".contains('
\u{1F4A9}'
));
1196 assert_eq
!(" \t a \t ".trim_left_matches(|c
: char| c
.is_whitespace()),
1198 assert_eq
!(" \t a \t ".trim_right_matches(|c
: char| c
.is_whitespace()),
1200 assert_eq
!(" \t a \t ".trim_matches(|c
: char| c
.is_whitespace()),
1202 assert_eq
!(" \t \t ".trim_left_matches(|c
: char| c
.is_whitespace()),
1204 assert_eq
!(" \t \t ".trim_right_matches(|c
: char| c
.is_whitespace()),
1206 assert_eq
!(" \t \t ".trim_matches(|c
: char| c
.is_whitespace()),
1212 assert_eq
!("".to_lowercase(), "");
1213 assert_eq
!("AÉDžaé ".to_lowercase(), "aédžaé ");
1215 // https://github.com/rust-lang/rust/issues/26035
1216 assert_eq
!("ΑΣ".to_lowercase(), "ας");
1217 assert_eq
!("Α'Σ".to_lowercase(), "α'ς");
1218 assert_eq
!("Α''Σ".to_lowercase(), "α''ς");
1220 assert_eq
!("ΑΣ Α".to_lowercase(), "ας α");
1221 assert_eq
!("Α'Σ Α".to_lowercase(), "α'ς α");
1222 assert_eq
!("Α''Σ Α".to_lowercase(), "α''ς α");
1224 assert_eq
!("ΑΣ' Α".to_lowercase(), "ας' α");
1225 assert_eq
!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1227 assert_eq
!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1228 assert_eq
!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1230 assert_eq
!("Α Σ".to_lowercase(), "α σ");
1231 assert_eq
!("Α 'Σ".to_lowercase(), "α 'σ");
1232 assert_eq
!("Α ''Σ".to_lowercase(), "α ''σ");
1234 assert_eq
!("Σ".to_lowercase(), "σ");
1235 assert_eq
!("'Σ".to_lowercase(), "'σ");
1236 assert_eq
!("''Σ".to_lowercase(), "''σ");
1238 assert_eq
!("ΑΣΑ".to_lowercase(), "ασα");
1239 assert_eq
!("ΑΣ'Α".to_lowercase(), "ασ'α");
1240 assert_eq
!("ΑΣ''Α".to_lowercase(), "ασ''α");
1245 assert_eq
!("".to_uppercase(), "");
1246 assert_eq
!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1250 fn test_into_string() {
1251 // The only way to acquire a Box<str> in the first place is through a String, so just
1252 // test that we can round-trip between Box<str> and String.
1253 let string
= String
::from("Some text goes here");
1254 assert_eq
!(string
.clone().into_boxed_str().into_string(), string
);
1258 fn test_box_slice_clone() {
1259 let data
= String
::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1260 let data2
= data
.clone().into_boxed_str().clone().into_string();
1262 assert_eq
!(data
, data2
);
1266 fn test_cow_from() {
1267 let borrowed
= "borrowed";
1268 let owned
= String
::from("owned");
1269 match (Cow
::from(owned
.clone()), Cow
::from(borrowed
)) {
1270 (Cow
::Owned(o
), Cow
::Borrowed(b
)) => assert
!(o
== owned
&& b
== borrowed
),
1271 _
=> panic
!("invalid `Cow::from`"),
1276 use std
::str::pattern
::Pattern
;
1277 use std
::str::pattern
::{Searcher, ReverseSearcher}
;
1278 use std
::str::pattern
::SearchStep
::{self, Match, Reject, Done}
;
1280 macro_rules
! make_test
{
1281 ($name
:ident
, $p
:expr
, $h
:expr
, [$
($e
:expr
,)*]) => {
1282 #[allow(unused_imports)]
1284 use std
::str::pattern
::SearchStep
::{Match, Reject}
;
1285 use super::{cmp_search_to_vec}
;
1288 cmp_search_to_vec(false, $p
, $h
, vec
![$
($e
),*]);
1292 cmp_search_to_vec(true, $p
, $h
, vec
![$
($e
),*]);
1298 fn cmp_search_to_vec
<'a
, P
: Pattern
<'a
>>(rev
: bool
, pat
: P
, haystack
: &'a
str,
1299 right
: Vec
<SearchStep
>)
1300 where P
::Searcher
: ReverseSearcher
<'a
>
1302 let mut searcher
= pat
.into_searcher(haystack
);
1305 match if !rev {searcher.next()}
else {searcher.next_back()}
{
1306 Match(a
, b
) => v
.push(Match(a
, b
)),
1307 Reject(a
, b
) => v
.push(Reject(a
, b
)),
1315 let mut first_index
= 0;
1318 for (i
, e
) in right
.iter().enumerate() {
1320 Match(a
, b
) | Reject(a
, b
)
1321 if a
<= b
&& a
== first_index
=> {
1331 if let Some(err
) = err
{
1332 panic
!("Input skipped range at {}", err
);
1335 if first_index
!= haystack
.len() {
1336 panic
!("Did not cover whole input");
1339 assert_eq
!(v
, right
);
1342 make_test
!(str_searcher_ascii_haystack
, "bb", "abbcbbd", [
1349 make_test
!(str_searcher_ascii_haystack_seq
, "bb", "abbcbbbbd", [
1357 make_test
!(str_searcher_empty_needle_ascii_haystack
, "", "abbcbbd", [
1374 make_test
!(str_searcher_mulibyte_haystack
, " ", "├──", [
1379 make_test
!(str_searcher_empty_needle_mulibyte_haystack
, "", "├──", [
1388 make_test
!(str_searcher_empty_needle_empty_haystack
, "", "", [
1391 make_test
!(str_searcher_nonempty_needle_empty_haystack
, "├", "", [
1393 make_test
!(char_searcher_ascii_haystack
, 'b'
, "abbcbbd", [
1402 make_test
!(char_searcher_mulibyte_haystack
, ' '
, "├──", [
1407 make_test
!(char_searcher_short_haystack
, '
\u{1F4A9}'
, "* \t", [
1415 macro_rules
! generate_iterator_test
{
1419 ($
($arg
:expr
),*) -> [$
($t
:tt
)*];
1422 with $fwd
:expr
, $bwd
:expr
;
1428 let res
= vec
![$
($t
)*];
1430 let fwd_vec
: Vec
<_
> = ($fwd
)($
($arg
),*).collect();
1431 assert_eq
!(fwd_vec
, res
);
1433 let mut bwd_vec
: Vec
<_
> = ($bwd
)($
($arg
),*).collect();
1435 assert_eq
!(bwd_vec
, res
);
1443 ($
($arg
:expr
),*) -> [$
($t
:tt
)*];
1452 let res
= vec
![$
($t
)*];
1454 let fwd_vec
: Vec
<_
> = ($fwd
)($
($arg
),*).collect();
1455 assert_eq
!(fwd_vec
, res
);
1462 generate_iterator_test
! {
1463 double_ended_split
{
1464 ("foo.bar.baz", '
.'
) -> ["foo", "bar", "baz"];
1465 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1467 with
str::split
, str::rsplit
;
1470 generate_iterator_test
! {
1471 double_ended_split_terminator
{
1472 ("foo;bar;baz;", '
;'
) -> ["foo", "bar", "baz"];
1474 with
str::split_terminator
, str::rsplit_terminator
;
1477 generate_iterator_test
! {
1478 double_ended_matches
{
1479 ("a1b2c3", char::is_numeric
) -> ["1", "2", "3"];
1481 with
str::matches
, str::rmatches
;
1484 generate_iterator_test
! {
1485 double_ended_match_indices
{
1486 ("a1b2c3", char::is_numeric
) -> [(1, "1"), (3, "2"), (5, "3")];
1488 with
str::match_indices
, str::rmatch_indices
;
1491 generate_iterator_test
! {
1492 not_double_ended_splitn
{
1493 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1498 generate_iterator_test
! {
1499 not_double_ended_rsplitn
{
1500 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1506 fn different_str_pattern_forwarding_lifetimes() {
1507 use std
::str::pattern
::Pattern
;
1509 fn foo
<'a
, P
>(p
: P
) where for<'b
> &'b P
: Pattern
<'a
> {
1519 use test
::{Bencher, black_box}
;
1522 fn char_iterator(b
: &mut Bencher
) {
1523 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1525 b
.iter(|| s
.chars().count());
1529 fn char_iterator_for(b
: &mut Bencher
) {
1530 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1533 for ch
in s
.chars() { black_box(ch); }
1538 fn char_iterator_ascii(b
: &mut Bencher
) {
1539 let s
= "Mary had a little lamb, Little lamb
1540 Mary had a little lamb, Little lamb
1541 Mary had a little lamb, Little lamb
1542 Mary had a little lamb, Little lamb
1543 Mary had a little lamb, Little lamb
1544 Mary had a little lamb, Little lamb";
1546 b
.iter(|| s
.chars().count());
1550 fn char_iterator_rev(b
: &mut Bencher
) {
1551 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1553 b
.iter(|| s
.chars().rev().count());
1557 fn char_iterator_rev_for(b
: &mut Bencher
) {
1558 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1561 for ch
in s
.chars().rev() { black_box(ch); }
1566 fn char_indicesator(b
: &mut Bencher
) {
1567 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1568 let len
= s
.chars().count();
1570 b
.iter(|| assert_eq
!(s
.char_indices().count(), len
));
1574 fn char_indicesator_rev(b
: &mut Bencher
) {
1575 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1576 let len
= s
.chars().count();
1578 b
.iter(|| assert_eq
!(s
.char_indices().rev().count(), len
));
1582 fn split_unicode_ascii(b
: &mut Bencher
) {
1583 let s
= "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
1585 b
.iter(|| assert_eq
!(s
.split('V'
).count(), 3));
1589 fn split_ascii(b
: &mut Bencher
) {
1590 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1591 let len
= s
.split(' '
).count();
1593 b
.iter(|| assert_eq
!(s
.split(' '
).count(), len
));
1597 fn split_extern_fn(b
: &mut Bencher
) {
1598 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1599 let len
= s
.split(' '
).count();
1600 fn pred(c
: char) -> bool { c == ' ' }
1602 b
.iter(|| assert_eq
!(s
.split(pred
).count(), len
));
1606 fn split_closure(b
: &mut Bencher
) {
1607 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1608 let len
= s
.split(' '
).count();
1610 b
.iter(|| assert_eq
!(s
.split(|c
: char| c
== ' '
).count(), len
));
1614 fn split_slice(b
: &mut Bencher
) {
1615 let s
= "Mary had a little lamb, Little lamb, little-lamb.";
1616 let len
= s
.split(' '
).count();
1618 let c
: &[char] = &[' '
];
1619 b
.iter(|| assert_eq
!(s
.split(c
).count(), len
));
1623 fn bench_join(b
: &mut Bencher
) {
1624 let s
= "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1626 let v
= vec
![s
, s
, s
, s
, s
, s
, s
, s
, s
, s
];
1628 assert_eq
!(v
.join(sep
).len(), s
.len() * 10 + sep
.len() * 9);
1633 fn bench_contains_short_short(b
: &mut Bencher
) {
1634 let haystack
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1638 assert
!(haystack
.contains(needle
));
1643 fn bench_contains_short_long(b
: &mut Bencher
) {
1645 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1646 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1647 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1648 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1649 tempus vel, gravida nec quam.
1651 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1652 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1653 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1654 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1655 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1656 interdum. Curabitur ut nisi justo.
1658 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1659 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1660 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1661 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1662 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1663 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1664 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1665 Aliquam sit amet placerat lorem.
1667 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1668 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1669 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1670 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1671 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1674 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1675 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1676 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1677 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1678 malesuada sollicitudin quam eu fermentum.";
1679 let needle
= "english";
1682 assert
!(!haystack
.contains(needle
));
1687 fn bench_contains_bad_naive(b
: &mut Bencher
) {
1688 let haystack
= "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1689 let needle
= "aaaaaaaab";
1692 assert
!(!haystack
.contains(needle
));
1697 fn bench_contains_equal(b
: &mut Bencher
) {
1698 let haystack
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1699 let needle
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
1702 assert
!(haystack
.contains(needle
));
1706 macro_rules
! make_test_inner
{
1707 ($s
:ident
, $code
:expr
, $name
:ident
, $
str:expr
) => {
1709 fn $
name(bencher
: &mut Bencher
) {
1712 bencher
.iter(|| $code
);
1717 macro_rules
! make_test
{
1718 ($name
:ident
, $s
:ident
, $code
:expr
) => {
1721 use test
::black_box
;
1723 // Short strings: 65 bytes each
1724 make_test_inner
!($s
, $code
, short_ascii
,
1725 "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
1726 make_test_inner
!($s
, $code
, short_mixed
,
1727 "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
1728 make_test_inner
!($s
, $code
, short_pile_of_poo
,
1729 "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
1730 make_test_inner
!($s
, $code
, long_lorem_ipsum
,"\
1731 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
1732 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
1733 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
1734 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
1735 tempus vel, gravida nec quam.
1737 In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
1738 sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
1739 diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
1740 lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
1741 eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
1742 interdum. Curabitur ut nisi justo.
1744 Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
1745 mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
1746 lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
1747 est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
1748 felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
1749 ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
1750 feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
1751 Aliquam sit amet placerat lorem.
1753 Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
1754 mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
1755 Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
1756 lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
1757 suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
1760 Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
1761 feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
1762 vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
1763 leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
1764 malesuada sollicitudin quam eu fermentum!");
1769 make_test
!(chars_count
, s
, s
.chars().count());
1771 make_test
!(contains_bang_str
, s
, s
.contains("!"));
1772 make_test
!(contains_bang_char
, s
, s
.contains('
!'
));
1774 make_test
!(match_indices_a_str
, s
, s
.match_indices("a").count());
1776 make_test
!(split_a_str
, s
, s
.split("a").count());
1778 make_test
!(trim_ascii_char
, s
, {
1779 use std
::ascii
::AsciiExt
;
1780 s
.trim_matches(|c
: char| c
.is_ascii())
1782 make_test
!(trim_left_ascii_char
, s
, {
1783 use std
::ascii
::AsciiExt
;
1784 s
.trim_left_matches(|c
: char| c
.is_ascii())
1786 make_test
!(trim_right_ascii_char
, s
, {
1787 use std
::ascii
::AsciiExt
;
1788 s
.trim_right_matches(|c
: char| c
.is_ascii())
1791 make_test
!(find_underscore_char
, s
, s
.find('_'
));
1792 make_test
!(rfind_underscore_char
, s
, s
.rfind('_'
));
1793 make_test
!(find_underscore_str
, s
, s
.find("_"));
1795 make_test
!(find_zzz_char
, s
, s
.find('
\u{1F4A4}'
));
1796 make_test
!(rfind_zzz_char
, s
, s
.rfind('
\u{1F4A4}'
));
1797 make_test
!(find_zzz_str
, s
, s
.find("\u{1F4A4}"));
1799 make_test
!(split_space_char
, s
, s
.split(' '
).count());
1800 make_test
!(split_terminator_space_char
, s
, s
.split_terminator(' '
).count());
1802 make_test
!(splitn_space_char
, s
, s
.splitn(10, ' '
).count());
1803 make_test
!(rsplitn_space_char
, s
, s
.rsplitn(10, ' '
).count());
1805 make_test
!(split_space_str
, s
, s
.split(" ").count());
1806 make_test
!(split_ad_str
, s
, s
.split("ad").count());