3 use std::collections::TryReserveError::*;
5 use std::ops::Bound::*;
6 use std::ops::RangeBounds;
10 pub trait IntoCow<'a, B: ?Sized>
14 fn into_cow(self) -> Cow<'a, B>;
17 impl<'a> IntoCow<'a, str> for String {
18 fn into_cow(self) -> Cow<'a, str> {
23 impl<'a> IntoCow<'a, str> for &'a str {
24 fn into_cow(self) -> Cow<'a, str> {
31 let owned: Option<std::string::String> = "string".parse().ok();
32 assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
36 fn test_from_cow_str() {
37 assert_eq!(String::from(Cow::Borrowed("string")), "string");
38 assert_eq!(String::from(Cow::Owned(String::from("string"))), "string");
42 fn test_unsized_to_string() {
44 let _: String = (*s).to_string();
49 let xs = b"hello".to_vec();
50 assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello"));
52 let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
53 assert_eq!(String::from_utf8(xs).unwrap(), String::from("ศไทย中华Việt Nam"));
55 let xs = b"hello\xFF".to_vec();
56 let err = String::from_utf8(xs).unwrap_err();
57 assert_eq!(err.as_bytes(), b"hello\xff");
58 let err_clone = err.clone();
59 assert_eq!(err, err_clone);
60 assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
61 assert_eq!(err_clone.utf8_error().valid_up_to(), 5);
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";
76 String::from_utf8_lossy(xs),
77 String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow()
80 let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
82 String::from_utf8_lossy(xs),
83 String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow()
86 let xs = b"\xF5foo\xF5\x80bar";
88 String::from_utf8_lossy(xs),
89 String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow()
92 let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
94 String::from_utf8_lossy(xs),
95 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow()
98 let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
100 String::from_utf8_lossy(xs),
101 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow()
104 let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
106 String::from_utf8_lossy(xs),
107 String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow()
111 let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
113 String::from_utf8_lossy(xs),
114 String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow()
119 fn test_from_utf16() {
122 String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
124 0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, 0xdf39,
125 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a,
129 String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
131 0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, 0xdc32,
132 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, 0xdc4d, 0x000a,
136 String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
138 0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, 0xdf11,
139 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, 0xdf15, 0xd800,
140 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, 0x000a,
144 String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
146 0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801, 0xdc9b,
147 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020, 0xd801, 0xdc88,
148 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f, 0xd801, 0xdc9c, 0xd801,
149 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc86,
153 // Issue #12318, even-numbered non-BMP planes
154 (String::from("\u{20000}"), vec![0xD840, 0xDC00]),
158 let (s, u) = (*p).clone();
159 let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
160 let u_as_string = String::from_utf16(&u).unwrap();
162 assert!(core::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
163 assert_eq!(s_as_utf16, u);
165 assert_eq!(u_as_string, s);
166 assert_eq!(String::from_utf16_lossy(&u), s);
168 assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
169 assert_eq!(u_as_string.encode_utf16().collect::<Vec<u16>>(), u);
174 fn test_utf16_invalid() {
175 // completely positive cases tested above.
177 assert!(String::from_utf16(&[0xD800]).is_err());
179 assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
182 assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
185 assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
189 fn test_from_utf16_lossy() {
190 // completely positive cases tested above.
192 assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from("\u{FFFD}"));
194 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]), String::from("\u{FFFD}\u{FFFD}"));
197 assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from("a\u{FFFD}"));
201 String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
202 String::from("\u{FFFD}𐒋\u{FFFD}")
207 fn test_push_bytes() {
208 let mut s = String::from("ABC");
210 let mv = s.as_mut_vec();
211 mv.extend_from_slice(&[b'D']);
213 assert_eq!(s, "ABCD");
218 let mut s = String::new();
220 assert_eq!(&s[0..], "");
222 assert_eq!(&s[0..], "abc");
223 s.push_str("ประเทศไทย中华Việt Nam");
224 assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
228 fn test_add_assign() {
229 let mut s = String::new();
231 assert_eq!(s.as_str(), "");
233 assert_eq!(s.as_str(), "abc");
234 s += "ประเทศไทย中华Việt Nam";
235 assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
240 let mut data = String::from("ประเทศไทย中");
242 data.push('b'); // 1 byte
243 data.push('¢'); // 2 byte
244 data.push('€'); // 3 byte
245 data.push('𤭢'); // 4 byte
246 assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
251 let mut data = String::from("ประเทศไทย中华b¢€𤭢");
252 assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
253 assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
254 assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
255 assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
256 assert_eq!(data.pop().unwrap(), '华');
257 assert_eq!(data, "ประเทศไทย中");
261 fn test_split_off_empty() {
262 let orig = "Hello, world!";
263 let mut split = String::from(orig);
264 let empty: String = split.split_off(orig.len());
265 assert!(empty.is_empty());
270 fn test_split_off_past_end() {
271 let orig = "Hello, world!";
272 let mut split = String::from(orig);
273 let _ = split.split_off(orig.len() + 1);
278 fn test_split_off_mid_char() {
279 let mut shan = String::from("山");
280 let _broken_mountain = shan.split_off(1);
284 fn test_split_off_ascii() {
285 let mut ab = String::from("ABCD");
286 let orig_capacity = ab.capacity();
287 let cd = ab.split_off(2);
288 assert_eq!(ab, "AB");
289 assert_eq!(cd, "CD");
290 assert_eq!(ab.capacity(), orig_capacity);
294 fn test_split_off_unicode() {
295 let mut nihon = String::from("日本語");
296 let orig_capacity = nihon.capacity();
297 let go = nihon.split_off("日本".len());
298 assert_eq!(nihon, "日本");
300 assert_eq!(nihon.capacity(), orig_capacity);
304 fn test_str_truncate() {
305 let mut s = String::from("12345");
307 assert_eq!(s, "12345");
309 assert_eq!(s, "123");
313 let mut s = String::from("12345");
322 fn test_str_truncate_invalid_len() {
323 let mut s = String::from("12345");
325 assert_eq!(s, "12345");
330 fn test_str_truncate_split_codepoint() {
331 let mut s = String::from("\u{FC}"); // ü
336 fn test_str_clear() {
337 let mut s = String::from("12345");
339 assert_eq!(s.len(), 0);
345 let a = String::from("12345");
348 assert_eq!(b.len(), 7);
349 assert_eq!(b, "1234522");
354 let mut s = "ศไทย中华Việt Nam; foobar".to_string();
355 assert_eq!(s.remove(0), 'ศ');
356 assert_eq!(s.len(), 33);
357 assert_eq!(s, "ไทย中华Việt Nam; foobar");
358 assert_eq!(s.remove(17), 'ệ');
359 assert_eq!(s, "ไทย中华Vit Nam; foobar");
365 "ศ".to_string().remove(1);
369 fn test_remove_matches() {
370 let mut s = "abc".to_string();
372 s.remove_matches('b');
374 s.remove_matches('b');
377 let mut s = "abcb".to_string();
379 s.remove_matches('b');
382 let mut s = "ศไทย中华Việt Nam; foobarศ".to_string();
383 s.remove_matches('ศ');
384 assert_eq!(s, "ไทย中华Việt Nam; foobar");
386 let mut s = "".to_string();
387 s.remove_matches("");
390 let mut s = "aaaaa".to_string();
391 s.remove_matches('a');
397 let mut s = String::from("α_β_γ");
400 assert_eq!(s, "α_β_γ");
402 s.retain(|c| c != '_');
403 assert_eq!(s, "αβγ");
405 s.retain(|c| c != 'β');
408 s.retain(|c| c == 'α');
414 let mut s = String::from("0è0");
415 let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
426 assert!(std::str::from_utf8(s.as_bytes()).is_ok());
431 let mut s = "foobar".to_string();
433 assert_eq!(s, "ệfoobar");
435 assert_eq!(s, "ệfooยbar");
441 "".to_string().insert(1, 't');
446 "ệ".to_string().insert(1, 't');
451 let s = "foobar".to_string();
452 assert_eq!("foobar", &s[..]);
453 assert_eq!("foo", &s[..3]);
454 assert_eq!("bar", &s[3..]);
455 assert_eq!("oob", &s[1..4]);
459 fn test_simple_types() {
460 assert_eq!(1.to_string(), "1");
461 assert_eq!((-1).to_string(), "-1");
462 assert_eq!(200.to_string(), "200");
463 assert_eq!(2.to_string(), "2");
464 assert_eq!(true.to_string(), "true");
465 assert_eq!(false.to_string(), "false");
466 assert_eq!(("hi".to_string()).to_string(), "hi");
471 let x: Vec<i32> = vec![];
472 assert_eq!(format!("{:?}", x), "[]");
473 assert_eq!(format!("{:?}", vec![1]), "[1]");
474 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
475 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
479 fn test_from_iterator() {
480 let s = "ศไทย中华Việt Nam".to_string();
484 let a: String = s.chars().collect();
487 let mut b = t.to_string();
491 let c: String = vec![t, u].into_iter().collect();
494 let mut d = t.to_string();
501 let mut s = String::from("αβγ");
502 assert_eq!(s.drain(2..4).collect::<String>(), "β");
505 let mut t = String::from("abcd");
507 assert_eq!(t, "abcd");
509 assert_eq!(t, "bcd");
511 assert_eq!(t, "bcd");
518 fn test_drain_start_overflow() {
519 let mut s = String::from("abc");
520 s.drain((Excluded(usize::MAX), Included(0)));
525 fn test_drain_end_overflow() {
526 let mut s = String::from("abc");
527 s.drain((Included(0), Included(usize::MAX)));
531 fn test_replace_range() {
532 let mut s = "Hello, world!".to_owned();
533 s.replace_range(7..12, "世界");
534 assert_eq!(s, "Hello, 世界!");
539 fn test_replace_range_char_boundary() {
540 let mut s = "Hello, 世界!".to_owned();
541 s.replace_range(..8, "");
545 fn test_replace_range_inclusive_range() {
546 let mut v = String::from("12345");
547 v.replace_range(2..=3, "789");
548 assert_eq!(v, "127895");
549 v.replace_range(1..=2, "A");
550 assert_eq!(v, "1A895");
555 fn test_replace_range_out_of_bounds() {
556 let mut s = String::from("12345");
557 s.replace_range(5..6, "789");
562 fn test_replace_range_inclusive_out_of_bounds() {
563 let mut s = String::from("12345");
564 s.replace_range(5..=5, "789");
569 fn test_replace_range_start_overflow() {
570 let mut s = String::from("123");
571 s.replace_range((Excluded(usize::MAX), Included(0)), "");
576 fn test_replace_range_end_overflow() {
577 let mut s = String::from("456");
578 s.replace_range((Included(0), Included(usize::MAX)), "");
582 fn test_replace_range_empty() {
583 let mut s = String::from("12345");
584 s.replace_range(1..2, "");
585 assert_eq!(s, "1345");
589 fn test_replace_range_unbounded() {
590 let mut s = String::from("12345");
591 s.replace_range(.., "");
596 fn test_replace_range_evil_start_bound() {
597 struct EvilRange(Cell<bool>);
599 impl RangeBounds<usize> for EvilRange {
600 fn start_bound(&self) -> Bound<&usize> {
601 Bound::Included(if self.0.get() {
608 fn end_bound(&self) -> Bound<&usize> {
613 let mut s = String::from("🦀");
614 s.replace_range(EvilRange(Cell::new(false)), "");
615 assert_eq!(Ok(""), str::from_utf8(s.as_bytes()));
619 fn test_replace_range_evil_end_bound() {
620 struct EvilRange(Cell<bool>);
622 impl RangeBounds<usize> for EvilRange {
623 fn start_bound(&self) -> Bound<&usize> {
626 fn end_bound(&self) -> Bound<&usize> {
627 Bound::Excluded(if self.0.get() {
636 let mut s = String::from("🦀");
637 s.replace_range(EvilRange(Cell::new(false)), "");
638 assert_eq!(Ok(""), str::from_utf8(s.as_bytes()));
642 fn test_extend_ref() {
643 let mut a = "foo".to_string();
644 a.extend(&['b', 'a', 'r']);
646 assert_eq!(&a, "foobar");
650 fn test_into_boxed_str() {
651 let xs = String::from("hello my name is bob");
652 let ys = xs.into_boxed_str();
653 assert_eq!(&*ys, "hello my name is bob");
657 fn test_reserve_exact() {
658 // This is all the same as test_reserve
660 let mut s = String::new();
661 assert_eq!(s.capacity(), 0);
664 assert!(s.capacity() >= 2);
670 assert!(s.capacity() >= 16);
672 assert!(s.capacity() >= 32);
677 assert!(s.capacity() >= 33)
681 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
682 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
683 fn test_try_reserve() {
684 // These are the interesting cases:
685 // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
686 // * > isize::MAX should always fail
687 // * On 16/32-bit should CapacityOverflow
688 // * On 64-bit should OOM
689 // * overflow may trigger when adding `len` to `cap` (in number of elements)
690 // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
692 const MAX_CAP: usize = isize::MAX as usize;
693 const MAX_USIZE: usize = usize::MAX;
695 // On 16/32-bit, we check that allocations don't exceed isize::MAX,
696 // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
697 // Any platform that succeeds for these requests is technically broken with
698 // ptr::offset because LLVM is the worst.
699 let guards_against_isize = usize::BITS < 64;
702 // Note: basic stuff is checked by test_reserve
703 let mut empty_string: String = String::new();
705 // Check isize::MAX doesn't count as an overflow
706 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
707 panic!("isize::MAX shouldn't trigger an overflow!");
709 // Play it again, frank! (just to be sure)
710 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
711 panic!("isize::MAX shouldn't trigger an overflow!");
714 if guards_against_isize {
715 // Check isize::MAX + 1 does count as overflow
716 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) {
718 panic!("isize::MAX + 1 should trigger an overflow!")
721 // Check usize::MAX does count as overflow
722 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) {
724 panic!("usize::MAX should trigger an overflow!")
727 // Check isize::MAX + 1 is an OOM
728 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
730 panic!("isize::MAX + 1 should trigger an OOM!")
733 // Check usize::MAX is an OOM
734 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
736 panic!("usize::MAX should trigger an OOM!")
742 // Same basic idea, but with non-zero len
743 let mut ten_bytes: String = String::from("0123456789");
745 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
746 panic!("isize::MAX shouldn't trigger an overflow!");
748 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
749 panic!("isize::MAX shouldn't trigger an overflow!");
751 if guards_against_isize {
752 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
754 panic!("isize::MAX + 1 should trigger an overflow!");
757 if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
759 panic!("isize::MAX + 1 should trigger an OOM!")
762 // Should always overflow in the add-to-len
763 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
765 panic!("usize::MAX should trigger an overflow!")
771 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
772 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
773 fn test_try_reserve_exact() {
774 // This is exactly the same as test_try_reserve with the method changed.
775 // See that test for comments.
777 const MAX_CAP: usize = isize::MAX as usize;
778 const MAX_USIZE: usize = usize::MAX;
780 let guards_against_isize = usize::BITS < 64;
783 let mut empty_string: String = String::new();
785 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
786 panic!("isize::MAX shouldn't trigger an overflow!");
788 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
789 panic!("isize::MAX shouldn't trigger an overflow!");
792 if guards_against_isize {
793 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
795 panic!("isize::MAX + 1 should trigger an overflow!")
798 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
800 panic!("usize::MAX should trigger an overflow!")
803 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
805 panic!("isize::MAX + 1 should trigger an OOM!")
808 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
810 panic!("usize::MAX should trigger an OOM!")
816 let mut ten_bytes: String = String::from("0123456789");
818 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
819 panic!("isize::MAX shouldn't trigger an overflow!");
821 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
822 panic!("isize::MAX shouldn't trigger an overflow!");
824 if guards_against_isize {
825 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
827 panic!("isize::MAX + 1 should trigger an overflow!");
830 if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
832 panic!("isize::MAX + 1 should trigger an OOM!")
835 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
837 panic!("usize::MAX should trigger an overflow!")
843 fn test_from_char() {
844 assert_eq!(String::from('a'), 'a'.to_string());
845 let s: String = 'x'.into();
846 assert_eq!(s, 'x'.to_string());
850 fn test_str_concat() {
851 let a: String = "hello".to_string();
852 let b: String = "world".to_string();
853 let s: String = format!("{}{}", a, b);
854 assert_eq!(s.as_bytes()[9], 'd' as u8);