1 // Copyright 2014 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::iter::repeat;
16 pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
17 fn into_cow(self) -> Cow<'a, B>;
20 impl<'a> IntoCow<'a, str> for String {
21 fn into_cow(self) -> Cow<'a, str> {
26 impl<'a> IntoCow<'a, str> for &'a str {
27 fn into_cow(self) -> Cow<'a, str> {
34 let owned: Option<::std::string::String> = "string".parse().ok();
35 assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
39 fn test_from_cow_str() {
40 assert_eq!(String::from(Cow::Borrowed("string")), "string");
41 assert_eq!(String::from(Cow::Owned(String::from("string"))), "string");
45 fn test_unsized_to_string() {
47 let _: String = (*s).to_string();
52 let xs = b"hello".to_vec();
53 assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello"));
55 let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
56 assert_eq!(String::from_utf8(xs).unwrap(),
57 String::from("ศไทย中华Việt Nam"));
59 let xs = b"hello\xFF".to_vec();
60 let err = String::from_utf8(xs).unwrap_err();
61 assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
65 fn test_from_utf8_lossy() {
67 let ys: Cow<str> = "hello".into_cow();
68 assert_eq!(String::from_utf8_lossy(xs), ys);
70 let xs = "ศไทย中华Việt Nam".as_bytes();
71 let ys: Cow<str> = "ศไทย中华Việt Nam".into_cow();
72 assert_eq!(String::from_utf8_lossy(xs), ys);
74 let xs = b"Hello\xC2 There\xFF Goodbye";
75 assert_eq!(String::from_utf8_lossy(xs),
76 String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
78 let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
79 assert_eq!(String::from_utf8_lossy(xs),
80 String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
82 let xs = b"\xF5foo\xF5\x80bar";
83 assert_eq!(String::from_utf8_lossy(xs),
84 String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
86 let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
87 assert_eq!(String::from_utf8_lossy(xs),
88 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
90 let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
91 assert_eq!(String::from_utf8_lossy(xs),
92 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
94 let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
95 assert_eq!(String::from_utf8_lossy(xs),
96 String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow());
99 let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
100 assert_eq!(String::from_utf8_lossy(xs),
101 String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
105 fn test_from_utf16() {
106 let pairs = [(String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
107 vec![0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800,
108 0xdf39, 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a]),
110 (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
111 vec![0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801,
112 0xdc32, 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801,
115 (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
116 vec![0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800,
117 0xdf11, 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800,
118 0xdf15, 0xd800, 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11,
121 (String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
122 vec![0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801,
123 0xdc9b, 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020,
124 0xd801, 0xdc88, 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f,
125 0xd801, 0xdc9c, 0xd801, 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020,
126 0xd801, 0xdc95, 0xd801, 0xdc86, 0x000a]),
127 // Issue #12318, even-numbered non-BMP planes
128 (String::from("\u{20000}"), vec![0xD840, 0xDC00])];
131 let (s, u) = (*p).clone();
132 let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
133 let u_as_string = String::from_utf16(&u).unwrap();
135 assert!(::std_unicode::str::is_utf16(&u));
136 assert_eq!(s_as_utf16, u);
138 assert_eq!(u_as_string, s);
139 assert_eq!(String::from_utf16_lossy(&u), s);
141 assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
142 assert_eq!(u_as_string.encode_utf16().collect::<Vec<u16>>(), u);
147 fn test_utf16_invalid() {
148 // completely positive cases tested above.
150 assert!(String::from_utf16(&[0xD800]).is_err());
152 assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
155 assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
158 assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
162 fn test_from_utf16_lossy() {
163 // completely positive cases tested above.
165 assert_eq!(String::from_utf16_lossy(&[0xD800]),
166 String::from("\u{FFFD}"));
168 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
169 String::from("\u{FFFD}\u{FFFD}"));
172 assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]),
173 String::from("a\u{FFFD}"));
176 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
177 String::from("\u{FFFD}𐒋\u{FFFD}"));
181 fn test_push_bytes() {
182 let mut s = String::from("ABC");
184 let mv = s.as_mut_vec();
185 mv.extend_from_slice(&[b'D']);
187 assert_eq!(s, "ABCD");
192 let mut s = String::new();
194 assert_eq!(&s[0..], "");
196 assert_eq!(&s[0..], "abc");
197 s.push_str("ประเทศไทย中华Việt Nam");
198 assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
202 fn test_add_assign() {
203 let mut s = String::new();
205 assert_eq!(s.as_str(), "");
207 assert_eq!(s.as_str(), "abc");
208 s += "ประเทศไทย中华Việt Nam";
209 assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
214 let mut data = String::from("ประเทศไทย中");
216 data.push('b'); // 1 byte
217 data.push('¢'); // 2 byte
218 data.push('€'); // 3 byte
219 data.push('𤭢'); // 4 byte
220 assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
225 let mut data = String::from("ประเทศไทย中华b¢€𤭢");
226 assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
227 assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
228 assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
229 assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
230 assert_eq!(data.pop().unwrap(), '华');
231 assert_eq!(data, "ประเทศไทย中");
235 fn test_split_off_empty() {
236 let orig = "Hello, world!";
237 let mut split = String::from(orig);
238 let empty: String = split.split_off(orig.len());
239 assert!(empty.is_empty());
244 fn test_split_off_past_end() {
245 let orig = "Hello, world!";
246 let mut split = String::from(orig);
247 split.split_off(orig.len() + 1);
252 fn test_split_off_mid_char() {
253 let mut orig = String::from("山");
258 fn test_split_off_ascii() {
259 let mut ab = String::from("ABCD");
260 let cd = ab.split_off(2);
261 assert_eq!(ab, "AB");
262 assert_eq!(cd, "CD");
266 fn test_split_off_unicode() {
267 let mut nihon = String::from("日本語");
268 let go = nihon.split_off("日本".len());
269 assert_eq!(nihon, "日本");
274 fn test_str_truncate() {
275 let mut s = String::from("12345");
277 assert_eq!(s, "12345");
279 assert_eq!(s, "123");
283 let mut s = String::from("12345");
292 fn test_str_truncate_invalid_len() {
293 let mut s = String::from("12345");
295 assert_eq!(s, "12345");
300 fn test_str_truncate_split_codepoint() {
301 let mut s = String::from("\u{FC}"); // ü
306 fn test_str_clear() {
307 let mut s = String::from("12345");
309 assert_eq!(s.len(), 0);
315 let a = String::from("12345");
318 assert_eq!(b.len(), 7);
319 assert_eq!(b, "1234522");
324 let mut s = "ศไทย中华Việt Nam; foobar".to_string();
325 assert_eq!(s.remove(0), 'ศ');
326 assert_eq!(s.len(), 33);
327 assert_eq!(s, "ไทย中华Việt Nam; foobar");
328 assert_eq!(s.remove(17), 'ệ');
329 assert_eq!(s, "ไทย中华Vit Nam; foobar");
335 "ศ".to_string().remove(1);
340 let mut s = "foobar".to_string();
342 assert_eq!(s, "ệfoobar");
344 assert_eq!(s, "ệfooยbar");
350 "".to_string().insert(1, 't');
355 "ệ".to_string().insert(1, 't');
360 let s = "foobar".to_string();
361 assert_eq!("foobar", &s[..]);
362 assert_eq!("foo", &s[..3]);
363 assert_eq!("bar", &s[3..]);
364 assert_eq!("oob", &s[1..4]);
368 fn test_simple_types() {
369 assert_eq!(1.to_string(), "1");
370 assert_eq!((-1).to_string(), "-1");
371 assert_eq!(200.to_string(), "200");
372 assert_eq!(2.to_string(), "2");
373 assert_eq!(true.to_string(), "true");
374 assert_eq!(false.to_string(), "false");
375 assert_eq!(("hi".to_string()).to_string(), "hi");
380 let x: Vec<i32> = vec![];
381 assert_eq!(format!("{:?}", x), "[]");
382 assert_eq!(format!("{:?}", vec![1]), "[1]");
383 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
384 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
388 fn test_from_iterator() {
389 let s = "ศไทย中华Việt Nam".to_string();
393 let a: String = s.chars().collect();
396 let mut b = t.to_string();
400 let c: String = vec![t, u].into_iter().collect();
403 let mut d = t.to_string();
410 let mut s = String::from("αβγ");
411 assert_eq!(s.drain(2..4).collect::<String>(), "β");
414 let mut t = String::from("abcd");
416 assert_eq!(t, "abcd");
418 assert_eq!(t, "bcd");
420 assert_eq!(t, "bcd");
426 fn test_extend_ref() {
427 let mut a = "foo".to_string();
428 a.extend(&['b', 'a', 'r']);
430 assert_eq!(&a, "foobar");
434 fn test_into_boxed_str() {
435 let xs = String::from("hello my name is bob");
436 let ys = xs.into_boxed_str();
437 assert_eq!(&*ys, "hello my name is bob");
441 fn bench_with_capacity(b: &mut Bencher) {
442 b.iter(|| String::with_capacity(100));
446 fn bench_push_str(b: &mut Bencher) {
447 let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
449 let mut r = String::new();
454 const REPETITIONS: u64 = 10_000;
457 fn bench_push_str_one_byte(b: &mut Bencher) {
458 b.bytes = REPETITIONS;
460 let mut r = String::new();
461 for _ in 0..REPETITIONS {
468 fn bench_push_char_one_byte(b: &mut Bencher) {
469 b.bytes = REPETITIONS;
471 let mut r = String::new();
472 for _ in 0..REPETITIONS {
479 fn bench_push_char_two_bytes(b: &mut Bencher) {
480 b.bytes = REPETITIONS * 2;
482 let mut r = String::new();
483 for _ in 0..REPETITIONS {
490 fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
491 let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
492 Lorem ipsum dolor sit amet, consectetur. ";
494 assert_eq!(100, s.len());
496 let _ = String::from_utf8_lossy(s);
501 fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
502 let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
503 assert_eq!(100, s.len());
505 let _ = String::from_utf8_lossy(s);
510 fn from_utf8_lossy_invalid(b: &mut Bencher) {
511 let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
513 let _ = String::from_utf8_lossy(s);
518 fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
519 let s = repeat(0xf5).take(100).collect::<Vec<_>>();
521 let _ = String::from_utf8_lossy(&s);
526 fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
527 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
528 Lorem ipsum dolor sit amet, consectetur. ";
529 // ensure our operation produces an exact-size string before we benchmark it
530 let mut r = String::with_capacity(s.len());
532 assert_eq!(r.len(), r.capacity());
534 let mut r = String::with_capacity(s.len());
542 fn bench_from_str(b: &mut Bencher) {
543 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
544 Lorem ipsum dolor sit amet, consectetur. ";
545 b.iter(|| String::from(s))
549 fn bench_from(b: &mut Bencher) {
550 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
551 Lorem ipsum dolor sit amet, consectetur. ";
552 b.iter(|| String::from(s))
556 fn bench_to_string(b: &mut Bencher) {
557 let s = "Hello there, the quick brown fox jumped over the lazy dog! \
558 Lorem ipsum dolor sit amet, consectetur. ";
559 b.iter(|| s.to_string())