2 use std::collections::TryReserveError::*;
5 pub trait IntoCow<'a, B: ?Sized>
9 fn into_cow(self) -> Cow<'a, B>;
12 impl<'a> IntoCow<'a, str> for String {
13 fn into_cow(self) -> Cow<'a, str> {
18 impl<'a> IntoCow<'a, str> for &'a str {
19 fn into_cow(self) -> Cow<'a, str> {
26 let owned: Option<std::string::String> = "string".parse().ok();
27 assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
31 fn test_from_cow_str() {
32 assert_eq!(String::from(Cow::Borrowed("string")), "string");
33 assert_eq!(String::from(Cow::Owned(String::from("string"))), "string");
37 fn test_unsized_to_string() {
39 let _: String = (*s).to_string();
44 let xs = b"hello".to_vec();
45 assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello"));
47 let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
48 assert_eq!(String::from_utf8(xs).unwrap(), String::from("ศไทย中华Việt Nam"));
50 let xs = b"hello\xFF".to_vec();
51 let err = String::from_utf8(xs).unwrap_err();
52 assert_eq!(err.as_bytes(), b"hello\xff");
53 let err_clone = err.clone();
54 assert_eq!(err, err_clone);
55 assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
56 assert_eq!(err_clone.utf8_error().valid_up_to(), 5);
60 fn test_from_utf8_lossy() {
62 let ys: Cow<'_, str> = "hello".into_cow();
63 assert_eq!(String::from_utf8_lossy(xs), ys);
65 let xs = "ศไทย中华Việt Nam".as_bytes();
66 let ys: Cow<'_, str> = "ศไทย中华Việt Nam".into_cow();
67 assert_eq!(String::from_utf8_lossy(xs), ys);
69 let xs = b"Hello\xC2 There\xFF Goodbye";
71 String::from_utf8_lossy(xs),
72 String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow()
75 let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
77 String::from_utf8_lossy(xs),
78 String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow()
81 let xs = b"\xF5foo\xF5\x80bar";
83 String::from_utf8_lossy(xs),
84 String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow()
87 let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
89 String::from_utf8_lossy(xs),
90 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow()
93 let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
95 String::from_utf8_lossy(xs),
96 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow()
99 let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
101 String::from_utf8_lossy(xs),
102 String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow()
106 let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
108 String::from_utf8_lossy(xs),
109 String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow()
114 fn test_from_utf16() {
117 String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
119 0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, 0xdf39,
120 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a,
124 String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
126 0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, 0xdc32,
127 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, 0xdc4d, 0x000a,
131 String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
133 0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, 0xdf11,
134 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, 0xdf15, 0xd800,
135 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, 0x000a,
139 String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
141 0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801, 0xdc9b,
142 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020, 0xd801, 0xdc88,
143 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f, 0xd801, 0xdc9c, 0xd801,
144 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc86,
148 // Issue #12318, even-numbered non-BMP planes
149 (String::from("\u{20000}"), vec![0xD840, 0xDC00]),
153 let (s, u) = (*p).clone();
154 let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
155 let u_as_string = String::from_utf16(&u).unwrap();
157 assert!(core::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
158 assert_eq!(s_as_utf16, u);
160 assert_eq!(u_as_string, s);
161 assert_eq!(String::from_utf16_lossy(&u), s);
163 assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
164 assert_eq!(u_as_string.encode_utf16().collect::<Vec<u16>>(), u);
169 fn test_utf16_invalid() {
170 // completely positive cases tested above.
172 assert!(String::from_utf16(&[0xD800]).is_err());
174 assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
177 assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
180 assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
184 fn test_from_utf16_lossy() {
185 // completely positive cases tested above.
187 assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from("\u{FFFD}"));
189 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]), String::from("\u{FFFD}\u{FFFD}"));
192 assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from("a\u{FFFD}"));
196 String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
197 String::from("\u{FFFD}𐒋\u{FFFD}")
202 fn test_push_bytes() {
203 let mut s = String::from("ABC");
205 let mv = s.as_mut_vec();
206 mv.extend_from_slice(&[b'D']);
208 assert_eq!(s, "ABCD");
213 let mut s = String::new();
215 assert_eq!(&s[0..], "");
217 assert_eq!(&s[0..], "abc");
218 s.push_str("ประเทศไทย中华Việt Nam");
219 assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
223 fn test_add_assign() {
224 let mut s = String::new();
226 assert_eq!(s.as_str(), "");
228 assert_eq!(s.as_str(), "abc");
229 s += "ประเทศไทย中华Việt Nam";
230 assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
235 let mut data = String::from("ประเทศไทย中");
237 data.push('b'); // 1 byte
238 data.push('¢'); // 2 byte
239 data.push('€'); // 3 byte
240 data.push('𤭢'); // 4 byte
241 assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
246 let mut data = String::from("ประเทศไทย中华b¢€𤭢");
247 assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
248 assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
249 assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
250 assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
251 assert_eq!(data.pop().unwrap(), '华');
252 assert_eq!(data, "ประเทศไทย中");
256 fn test_split_off_empty() {
257 let orig = "Hello, world!";
258 let mut split = String::from(orig);
259 let empty: String = split.split_off(orig.len());
260 assert!(empty.is_empty());
265 fn test_split_off_past_end() {
266 let orig = "Hello, world!";
267 let mut split = String::from(orig);
268 let _ = split.split_off(orig.len() + 1);
273 fn test_split_off_mid_char() {
274 let mut orig = String::from("山");
275 let _ = orig.split_off(1);
279 fn test_split_off_ascii() {
280 let mut ab = String::from("ABCD");
281 let orig_capacity = ab.capacity();
282 let cd = ab.split_off(2);
283 assert_eq!(ab, "AB");
284 assert_eq!(cd, "CD");
285 assert_eq!(ab.capacity(), orig_capacity);
289 fn test_split_off_unicode() {
290 let mut nihon = String::from("日本語");
291 let orig_capacity = nihon.capacity();
292 let go = nihon.split_off("日本".len());
293 assert_eq!(nihon, "日本");
295 assert_eq!(nihon.capacity(), orig_capacity);
299 fn test_str_truncate() {
300 let mut s = String::from("12345");
302 assert_eq!(s, "12345");
304 assert_eq!(s, "123");
308 let mut s = String::from("12345");
317 fn test_str_truncate_invalid_len() {
318 let mut s = String::from("12345");
320 assert_eq!(s, "12345");
325 fn test_str_truncate_split_codepoint() {
326 let mut s = String::from("\u{FC}"); // ü
331 fn test_str_clear() {
332 let mut s = String::from("12345");
334 assert_eq!(s.len(), 0);
340 let a = String::from("12345");
343 assert_eq!(b.len(), 7);
344 assert_eq!(b, "1234522");
349 let mut s = "ศไทย中华Việt Nam; foobar".to_string();
350 assert_eq!(s.remove(0), 'ศ');
351 assert_eq!(s.len(), 33);
352 assert_eq!(s, "ไทย中华Việt Nam; foobar");
353 assert_eq!(s.remove(17), 'ệ');
354 assert_eq!(s, "ไทย中华Vit Nam; foobar");
360 "ศ".to_string().remove(1);
365 let mut s = String::from("α_β_γ");
368 assert_eq!(s, "α_β_γ");
370 s.retain(|c| c != '_');
371 assert_eq!(s, "αβγ");
373 s.retain(|c| c != 'β');
376 s.retain(|c| c == 'α');
385 let mut s = "foobar".to_string();
387 assert_eq!(s, "ệfoobar");
389 assert_eq!(s, "ệfooยbar");
395 "".to_string().insert(1, 't');
400 "ệ".to_string().insert(1, 't');
405 let s = "foobar".to_string();
406 assert_eq!("foobar", &s[..]);
407 assert_eq!("foo", &s[..3]);
408 assert_eq!("bar", &s[3..]);
409 assert_eq!("oob", &s[1..4]);
413 fn test_simple_types() {
414 assert_eq!(1.to_string(), "1");
415 assert_eq!((-1).to_string(), "-1");
416 assert_eq!(200.to_string(), "200");
417 assert_eq!(2.to_string(), "2");
418 assert_eq!(true.to_string(), "true");
419 assert_eq!(false.to_string(), "false");
420 assert_eq!(("hi".to_string()).to_string(), "hi");
425 let x: Vec<i32> = vec![];
426 assert_eq!(format!("{:?}", x), "[]");
427 assert_eq!(format!("{:?}", vec![1]), "[1]");
428 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
429 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
433 fn test_from_iterator() {
434 let s = "ศไทย中华Việt Nam".to_string();
438 let a: String = s.chars().collect();
441 let mut b = t.to_string();
445 let c: String = vec![t, u].into_iter().collect();
448 let mut d = t.to_string();
455 let mut s = String::from("αβγ");
456 assert_eq!(s.drain(2..4).collect::<String>(), "β");
459 let mut t = String::from("abcd");
461 assert_eq!(t, "abcd");
463 assert_eq!(t, "bcd");
465 assert_eq!(t, "bcd");
471 fn test_replace_range() {
472 let mut s = "Hello, world!".to_owned();
473 s.replace_range(7..12, "世界");
474 assert_eq!(s, "Hello, 世界!");
479 fn test_replace_range_char_boundary() {
480 let mut s = "Hello, 世界!".to_owned();
481 s.replace_range(..8, "");
485 fn test_replace_range_inclusive_range() {
486 let mut v = String::from("12345");
487 v.replace_range(2..=3, "789");
488 assert_eq!(v, "127895");
489 v.replace_range(1..=2, "A");
490 assert_eq!(v, "1A895");
495 fn test_replace_range_out_of_bounds() {
496 let mut s = String::from("12345");
497 s.replace_range(5..6, "789");
502 fn test_replace_range_inclusive_out_of_bounds() {
503 let mut s = String::from("12345");
504 s.replace_range(5..=5, "789");
508 fn test_replace_range_empty() {
509 let mut s = String::from("12345");
510 s.replace_range(1..2, "");
511 assert_eq!(s, "1345");
515 fn test_replace_range_unbounded() {
516 let mut s = String::from("12345");
517 s.replace_range(.., "");
522 fn test_extend_ref() {
523 let mut a = "foo".to_string();
524 a.extend(&['b', 'a', 'r']);
526 assert_eq!(&a, "foobar");
530 fn test_into_boxed_str() {
531 let xs = String::from("hello my name is bob");
532 let ys = xs.into_boxed_str();
533 assert_eq!(&*ys, "hello my name is bob");
537 fn test_reserve_exact() {
538 // This is all the same as test_reserve
540 let mut s = String::new();
541 assert_eq!(s.capacity(), 0);
544 assert!(s.capacity() >= 2);
550 assert!(s.capacity() >= 16);
552 assert!(s.capacity() >= 32);
557 assert!(s.capacity() >= 33)
561 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
562 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
563 fn test_try_reserve() {
564 // These are the interesting cases:
565 // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
566 // * > isize::MAX should always fail
567 // * On 16/32-bit should CapacityOverflow
568 // * On 64-bit should OOM
569 // * overflow may trigger when adding `len` to `cap` (in number of elements)
570 // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
572 const MAX_CAP: usize = isize::MAX as usize;
573 const MAX_USIZE: usize = usize::MAX;
575 // On 16/32-bit, we check that allocations don't exceed isize::MAX,
576 // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
577 // Any platform that succeeds for these requests is technically broken with
578 // ptr::offset because LLVM is the worst.
579 let guards_against_isize = size_of::<usize>() < 8;
582 // Note: basic stuff is checked by test_reserve
583 let mut empty_string: String = String::new();
585 // Check isize::MAX doesn't count as an overflow
586 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
587 panic!("isize::MAX shouldn't trigger an overflow!");
589 // Play it again, frank! (just to be sure)
590 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
591 panic!("isize::MAX shouldn't trigger an overflow!");
594 if guards_against_isize {
595 // Check isize::MAX + 1 does count as overflow
596 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) {
598 panic!("isize::MAX + 1 should trigger an overflow!")
601 // Check usize::MAX does count as overflow
602 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) {
604 panic!("usize::MAX should trigger an overflow!")
607 // Check isize::MAX + 1 is an OOM
608 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
610 panic!("isize::MAX + 1 should trigger an OOM!")
613 // Check usize::MAX is an OOM
614 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
616 panic!("usize::MAX should trigger an OOM!")
622 // Same basic idea, but with non-zero len
623 let mut ten_bytes: String = String::from("0123456789");
625 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
626 panic!("isize::MAX shouldn't trigger an overflow!");
628 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
629 panic!("isize::MAX shouldn't trigger an overflow!");
631 if guards_against_isize {
632 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
634 panic!("isize::MAX + 1 should trigger an overflow!");
637 if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
639 panic!("isize::MAX + 1 should trigger an OOM!")
642 // Should always overflow in the add-to-len
643 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
645 panic!("usize::MAX should trigger an overflow!")
651 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
652 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
653 fn test_try_reserve_exact() {
654 // This is exactly the same as test_try_reserve with the method changed.
655 // See that test for comments.
657 const MAX_CAP: usize = isize::MAX as usize;
658 const MAX_USIZE: usize = usize::MAX;
660 let guards_against_isize = size_of::<usize>() < 8;
663 let mut empty_string: String = String::new();
665 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
666 panic!("isize::MAX shouldn't trigger an overflow!");
668 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
669 panic!("isize::MAX shouldn't trigger an overflow!");
672 if guards_against_isize {
673 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
675 panic!("isize::MAX + 1 should trigger an overflow!")
678 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
680 panic!("usize::MAX should trigger an overflow!")
683 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
685 panic!("isize::MAX + 1 should trigger an OOM!")
688 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
690 panic!("usize::MAX should trigger an OOM!")
696 let mut ten_bytes: String = String::from("0123456789");
698 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
699 panic!("isize::MAX shouldn't trigger an overflow!");
701 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
702 panic!("isize::MAX shouldn't trigger an overflow!");
704 if guards_against_isize {
705 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
707 panic!("isize::MAX + 1 should trigger an overflow!");
710 if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
712 panic!("isize::MAX + 1 should trigger an OOM!")
715 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
717 panic!("usize::MAX should trigger an overflow!")
723 fn test_from_char() {
724 assert_eq!(String::from('a'), 'a'.to_string());
725 let s: String = 'x'.into();
726 assert_eq!(s, 'x'.to_string());
730 fn test_str_concat() {
731 let a: String = "hello".to_string();
732 let b: String = "world".to_string();
733 let s: String = format!("{}{}", a, b);
734 assert_eq!(s.as_bytes()[9], 'd' as u8);