2 use std::collections::TryReserveError::*;
4 use std::{usize, isize};
6 pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
7 fn into_cow(self) -> Cow<'a, B>;
10 impl<'a> IntoCow<'a, str> for String {
11 fn into_cow(self) -> Cow<'a, str> {
16 impl<'a> IntoCow<'a, str> for &'a str {
17 fn into_cow(self) -> Cow<'a, str> {
24 let owned: Option<std::string::String> = "string".parse().ok();
25 assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
29 fn test_from_cow_str() {
30 assert_eq!(String::from(Cow::Borrowed("string")), "string");
31 assert_eq!(String::from(Cow::Owned(String::from("string"))), "string");
35 fn test_unsized_to_string() {
37 let _: String = (*s).to_string();
42 let xs = b"hello".to_vec();
43 assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello"));
45 let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
46 assert_eq!(String::from_utf8(xs).unwrap(),
47 String::from("ศไทย中华Việt Nam"));
49 let xs = b"hello\xFF".to_vec();
50 let err = String::from_utf8(xs).unwrap_err();
51 assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
55 fn test_from_utf8_lossy() {
57 let ys: Cow<'_, str> = "hello".into_cow();
58 assert_eq!(String::from_utf8_lossy(xs), ys);
60 let xs = "ศไทย中华Việt Nam".as_bytes();
61 let ys: Cow<'_, str> = "ศไทย中华Việt Nam".into_cow();
62 assert_eq!(String::from_utf8_lossy(xs), ys);
64 let xs = b"Hello\xC2 There\xFF Goodbye";
65 assert_eq!(String::from_utf8_lossy(xs),
66 String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
68 let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
69 assert_eq!(String::from_utf8_lossy(xs),
70 String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
72 let xs = b"\xF5foo\xF5\x80bar";
73 assert_eq!(String::from_utf8_lossy(xs),
74 String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
76 let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
77 assert_eq!(String::from_utf8_lossy(xs),
78 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
80 let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
81 assert_eq!(String::from_utf8_lossy(xs),
82 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
84 let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
85 assert_eq!(String::from_utf8_lossy(xs),
86 String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow());
89 let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
90 assert_eq!(String::from_utf8_lossy(xs),
91 String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
95 fn test_from_utf16() {
96 let pairs = [(String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
97 vec![0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800,
98 0xdf39, 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a]),
100 (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
101 vec![0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801,
102 0xdc32, 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801,
105 (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
106 vec![0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800,
107 0xdf11, 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800,
108 0xdf15, 0xd800, 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11,
111 (String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
112 vec![0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801,
113 0xdc9b, 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020,
114 0xd801, 0xdc88, 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f,
115 0xd801, 0xdc9c, 0xd801, 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020,
116 0xd801, 0xdc95, 0xd801, 0xdc86, 0x000a]),
117 // Issue #12318, even-numbered non-BMP planes
118 (String::from("\u{20000}"), vec![0xD840, 0xDC00])];
121 let (s, u) = (*p).clone();
122 let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
123 let u_as_string = String::from_utf16(&u).unwrap();
125 assert!(core::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
126 assert_eq!(s_as_utf16, u);
128 assert_eq!(u_as_string, s);
129 assert_eq!(String::from_utf16_lossy(&u), s);
131 assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
132 assert_eq!(u_as_string.encode_utf16().collect::<Vec<u16>>(), u);
137 fn test_utf16_invalid() {
138 // completely positive cases tested above.
140 assert!(String::from_utf16(&[0xD800]).is_err());
142 assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
145 assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
148 assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
152 fn test_from_utf16_lossy() {
153 // completely positive cases tested above.
155 assert_eq!(String::from_utf16_lossy(&[0xD800]),
156 String::from("\u{FFFD}"));
158 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
159 String::from("\u{FFFD}\u{FFFD}"));
162 assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]),
163 String::from("a\u{FFFD}"));
166 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
167 String::from("\u{FFFD}𐒋\u{FFFD}"));
171 fn test_push_bytes() {
172 let mut s = String::from("ABC");
174 let mv = s.as_mut_vec();
175 mv.extend_from_slice(&[b'D']);
177 assert_eq!(s, "ABCD");
182 let mut s = String::new();
184 assert_eq!(&s[0..], "");
186 assert_eq!(&s[0..], "abc");
187 s.push_str("ประเทศไทย中华Việt Nam");
188 assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
192 fn test_add_assign() {
193 let mut s = String::new();
195 assert_eq!(s.as_str(), "");
197 assert_eq!(s.as_str(), "abc");
198 s += "ประเทศไทย中华Việt Nam";
199 assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
204 let mut data = String::from("ประเทศไทย中");
206 data.push('b'); // 1 byte
207 data.push('¢'); // 2 byte
208 data.push('€'); // 3 byte
209 data.push('𤭢'); // 4 byte
210 assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
215 let mut data = String::from("ประเทศไทย中华b¢€𤭢");
216 assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
217 assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
218 assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
219 assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
220 assert_eq!(data.pop().unwrap(), '华');
221 assert_eq!(data, "ประเทศไทย中");
225 fn test_split_off_empty() {
226 let orig = "Hello, world!";
227 let mut split = String::from(orig);
228 let empty: String = split.split_off(orig.len());
229 assert!(empty.is_empty());
234 fn test_split_off_past_end() {
235 let orig = "Hello, world!";
236 let mut split = String::from(orig);
237 split.split_off(orig.len() + 1);
242 fn test_split_off_mid_char() {
243 let mut orig = String::from("山");
248 fn test_split_off_ascii() {
249 let mut ab = String::from("ABCD");
250 let cd = ab.split_off(2);
251 assert_eq!(ab, "AB");
252 assert_eq!(cd, "CD");
256 fn test_split_off_unicode() {
257 let mut nihon = String::from("日本語");
258 let go = nihon.split_off("日本".len());
259 assert_eq!(nihon, "日本");
264 fn test_str_truncate() {
265 let mut s = String::from("12345");
267 assert_eq!(s, "12345");
269 assert_eq!(s, "123");
273 let mut s = String::from("12345");
282 fn test_str_truncate_invalid_len() {
283 let mut s = String::from("12345");
285 assert_eq!(s, "12345");
290 fn test_str_truncate_split_codepoint() {
291 let mut s = String::from("\u{FC}"); // ü
296 fn test_str_clear() {
297 let mut s = String::from("12345");
299 assert_eq!(s.len(), 0);
305 let a = String::from("12345");
308 assert_eq!(b.len(), 7);
309 assert_eq!(b, "1234522");
314 let mut s = "ศไทย中华Việt Nam; foobar".to_string();
315 assert_eq!(s.remove(0), 'ศ');
316 assert_eq!(s.len(), 33);
317 assert_eq!(s, "ไทย中华Việt Nam; foobar");
318 assert_eq!(s.remove(17), 'ệ');
319 assert_eq!(s, "ไทย中华Vit Nam; foobar");
325 "ศ".to_string().remove(1);
330 let mut s = String::from("α_β_γ");
333 assert_eq!(s, "α_β_γ");
335 s.retain(|c| c != '_');
336 assert_eq!(s, "αβγ");
338 s.retain(|c| c != 'β');
341 s.retain(|c| c == 'α');
350 let mut s = "foobar".to_string();
352 assert_eq!(s, "ệfoobar");
354 assert_eq!(s, "ệfooยbar");
360 "".to_string().insert(1, 't');
365 "ệ".to_string().insert(1, 't');
370 let s = "foobar".to_string();
371 assert_eq!("foobar", &s[..]);
372 assert_eq!("foo", &s[..3]);
373 assert_eq!("bar", &s[3..]);
374 assert_eq!("oob", &s[1..4]);
378 fn test_simple_types() {
379 assert_eq!(1.to_string(), "1");
380 assert_eq!((-1).to_string(), "-1");
381 assert_eq!(200.to_string(), "200");
382 assert_eq!(2.to_string(), "2");
383 assert_eq!(true.to_string(), "true");
384 assert_eq!(false.to_string(), "false");
385 assert_eq!(("hi".to_string()).to_string(), "hi");
390 let x: Vec<i32> = vec![];
391 assert_eq!(format!("{:?}", x), "[]");
392 assert_eq!(format!("{:?}", vec![1]), "[1]");
393 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
394 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
398 fn test_from_iterator() {
399 let s = "ศไทย中华Việt Nam".to_string();
403 let a: String = s.chars().collect();
406 let mut b = t.to_string();
410 let c: String = vec![t, u].into_iter().collect();
413 let mut d = t.to_string();
420 let mut s = String::from("αβγ");
421 assert_eq!(s.drain(2..4).collect::<String>(), "β");
424 let mut t = String::from("abcd");
426 assert_eq!(t, "abcd");
428 assert_eq!(t, "bcd");
430 assert_eq!(t, "bcd");
436 fn test_replace_range() {
437 let mut s = "Hello, world!".to_owned();
438 s.replace_range(7..12, "世界");
439 assert_eq!(s, "Hello, 世界!");
444 fn test_replace_range_char_boundary() {
445 let mut s = "Hello, 世界!".to_owned();
446 s.replace_range(..8, "");
450 fn test_replace_range_inclusive_range() {
451 let mut v = String::from("12345");
452 v.replace_range(2..=3, "789");
453 assert_eq!(v, "127895");
454 v.replace_range(1..=2, "A");
455 assert_eq!(v, "1A895");
460 fn test_replace_range_out_of_bounds() {
461 let mut s = String::from("12345");
462 s.replace_range(5..6, "789");
467 fn test_replace_range_inclusive_out_of_bounds() {
468 let mut s = String::from("12345");
469 s.replace_range(5..=5, "789");
473 fn test_replace_range_empty() {
474 let mut s = String::from("12345");
475 s.replace_range(1..2, "");
476 assert_eq!(s, "1345");
480 fn test_replace_range_unbounded() {
481 let mut s = String::from("12345");
482 s.replace_range(.., "");
487 fn test_extend_ref() {
488 let mut a = "foo".to_string();
489 a.extend(&['b', 'a', 'r']);
491 assert_eq!(&a, "foobar");
495 fn test_into_boxed_str() {
496 let xs = String::from("hello my name is bob");
497 let ys = xs.into_boxed_str();
498 assert_eq!(&*ys, "hello my name is bob");
502 fn test_reserve_exact() {
503 // This is all the same as test_reserve
505 let mut s = String::new();
506 assert_eq!(s.capacity(), 0);
509 assert!(s.capacity() >= 2);
515 assert!(s.capacity() >= 16);
517 assert!(s.capacity() >= 32);
522 assert!(s.capacity() >= 33)
526 #[cfg(not(miri))] // Miri does not support signalling OOM
527 fn test_try_reserve() {
529 // These are the interesting cases:
530 // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
531 // * > isize::MAX should always fail
532 // * On 16/32-bit should CapacityOverflow
533 // * On 64-bit should OOM
534 // * overflow may trigger when adding `len` to `cap` (in number of elements)
535 // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
537 const MAX_CAP: usize = isize::MAX as usize;
538 const MAX_USIZE: usize = usize::MAX;
540 // On 16/32-bit, we check that allocations don't exceed isize::MAX,
541 // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
542 // Any platform that succeeds for these requests is technically broken with
543 // ptr::offset because LLVM is the worst.
544 let guards_against_isize = size_of::<usize>() < 8;
547 // Note: basic stuff is checked by test_reserve
548 let mut empty_string: String = String::new();
550 // Check isize::MAX doesn't count as an overflow
551 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
552 panic!("isize::MAX shouldn't trigger an overflow!");
554 // Play it again, frank! (just to be sure)
555 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
556 panic!("isize::MAX shouldn't trigger an overflow!");
559 if guards_against_isize {
560 // Check isize::MAX + 1 does count as overflow
561 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) {
562 } else { panic!("isize::MAX + 1 should trigger an overflow!") }
564 // Check usize::MAX does count as overflow
565 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) {
566 } else { panic!("usize::MAX should trigger an overflow!") }
568 // Check isize::MAX + 1 is an OOM
569 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
570 } else { panic!("isize::MAX + 1 should trigger an OOM!") }
572 // Check usize::MAX is an OOM
573 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
574 } else { panic!("usize::MAX should trigger an OOM!") }
580 // Same basic idea, but with non-zero len
581 let mut ten_bytes: String = String::from("0123456789");
583 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
584 panic!("isize::MAX shouldn't trigger an overflow!");
586 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
587 panic!("isize::MAX shouldn't trigger an overflow!");
589 if guards_against_isize {
590 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
591 } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
593 if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
594 } else { panic!("isize::MAX + 1 should trigger an OOM!") }
596 // Should always overflow in the add-to-len
597 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
598 } else { panic!("usize::MAX should trigger an overflow!") }
604 #[cfg(not(miri))] // Miri does not support signalling OOM
605 fn test_try_reserve_exact() {
607 // This is exactly the same as test_try_reserve with the method changed.
608 // See that test for comments.
610 const MAX_CAP: usize = isize::MAX as usize;
611 const MAX_USIZE: usize = usize::MAX;
613 let guards_against_isize = size_of::<usize>() < 8;
616 let mut empty_string: String = String::new();
618 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
619 panic!("isize::MAX shouldn't trigger an overflow!");
621 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
622 panic!("isize::MAX shouldn't trigger an overflow!");
625 if guards_against_isize {
626 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
627 } else { panic!("isize::MAX + 1 should trigger an overflow!") }
629 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
630 } else { panic!("usize::MAX should trigger an overflow!") }
632 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
633 } else { panic!("isize::MAX + 1 should trigger an OOM!") }
635 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
636 } else { panic!("usize::MAX should trigger an OOM!") }
642 let mut ten_bytes: String = String::from("0123456789");
644 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
645 panic!("isize::MAX shouldn't trigger an overflow!");
647 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
648 panic!("isize::MAX shouldn't trigger an overflow!");
650 if guards_against_isize {
651 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
652 } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
654 if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
655 } else { panic!("isize::MAX + 1 should trigger an OOM!") }
657 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
658 } else { panic!("usize::MAX should trigger an overflow!") }