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);
370 let mut s = String::from("α_β_γ");
373 assert_eq!(s, "α_β_γ");
375 s.retain(|c| c != '_');
376 assert_eq!(s, "αβγ");
378 s.retain(|c| c != 'β');
381 s.retain(|c| c == 'α');
387 let mut s = String::from("0è0");
388 let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
399 assert!(std::str::from_utf8(s.as_bytes()).is_ok());
404 let mut s = "foobar".to_string();
406 assert_eq!(s, "ệfoobar");
408 assert_eq!(s, "ệfooยbar");
414 "".to_string().insert(1, 't');
419 "ệ".to_string().insert(1, 't');
424 let s = "foobar".to_string();
425 assert_eq!("foobar", &s[..]);
426 assert_eq!("foo", &s[..3]);
427 assert_eq!("bar", &s[3..]);
428 assert_eq!("oob", &s[1..4]);
432 fn test_simple_types() {
433 assert_eq!(1.to_string(), "1");
434 assert_eq!((-1).to_string(), "-1");
435 assert_eq!(200.to_string(), "200");
436 assert_eq!(2.to_string(), "2");
437 assert_eq!(true.to_string(), "true");
438 assert_eq!(false.to_string(), "false");
439 assert_eq!(("hi".to_string()).to_string(), "hi");
444 let x: Vec<i32> = vec![];
445 assert_eq!(format!("{:?}", x), "[]");
446 assert_eq!(format!("{:?}", vec![1]), "[1]");
447 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
448 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
452 fn test_from_iterator() {
453 let s = "ศไทย中华Việt Nam".to_string();
457 let a: String = s.chars().collect();
460 let mut b = t.to_string();
464 let c: String = vec![t, u].into_iter().collect();
467 let mut d = t.to_string();
474 let mut s = String::from("αβγ");
475 assert_eq!(s.drain(2..4).collect::<String>(), "β");
478 let mut t = String::from("abcd");
480 assert_eq!(t, "abcd");
482 assert_eq!(t, "bcd");
484 assert_eq!(t, "bcd");
491 fn test_drain_start_overflow() {
492 let mut s = String::from("abc");
493 s.drain((Excluded(usize::MAX), Included(0)));
498 fn test_drain_end_overflow() {
499 let mut s = String::from("abc");
500 s.drain((Included(0), Included(usize::MAX)));
504 fn test_replace_range() {
505 let mut s = "Hello, world!".to_owned();
506 s.replace_range(7..12, "世界");
507 assert_eq!(s, "Hello, 世界!");
512 fn test_replace_range_char_boundary() {
513 let mut s = "Hello, 世界!".to_owned();
514 s.replace_range(..8, "");
518 fn test_replace_range_inclusive_range() {
519 let mut v = String::from("12345");
520 v.replace_range(2..=3, "789");
521 assert_eq!(v, "127895");
522 v.replace_range(1..=2, "A");
523 assert_eq!(v, "1A895");
528 fn test_replace_range_out_of_bounds() {
529 let mut s = String::from("12345");
530 s.replace_range(5..6, "789");
535 fn test_replace_range_inclusive_out_of_bounds() {
536 let mut s = String::from("12345");
537 s.replace_range(5..=5, "789");
542 fn test_replace_range_start_overflow() {
543 let mut s = String::from("123");
544 s.replace_range((Excluded(usize::MAX), Included(0)), "");
549 fn test_replace_range_end_overflow() {
550 let mut s = String::from("456");
551 s.replace_range((Included(0), Included(usize::MAX)), "");
555 fn test_replace_range_empty() {
556 let mut s = String::from("12345");
557 s.replace_range(1..2, "");
558 assert_eq!(s, "1345");
562 fn test_replace_range_unbounded() {
563 let mut s = String::from("12345");
564 s.replace_range(.., "");
569 fn test_replace_range_evil_start_bound() {
570 struct EvilRange(Cell<bool>);
572 impl RangeBounds<usize> for EvilRange {
573 fn start_bound(&self) -> Bound<&usize> {
574 Bound::Included(if self.0.get() {
581 fn end_bound(&self) -> Bound<&usize> {
586 let mut s = String::from("🦀");
587 s.replace_range(EvilRange(Cell::new(false)), "");
588 assert_eq!(Ok(""), str::from_utf8(s.as_bytes()));
592 fn test_replace_range_evil_end_bound() {
593 struct EvilRange(Cell<bool>);
595 impl RangeBounds<usize> for EvilRange {
596 fn start_bound(&self) -> Bound<&usize> {
599 fn end_bound(&self) -> Bound<&usize> {
600 Bound::Excluded(if self.0.get() {
609 let mut s = String::from("🦀");
610 s.replace_range(EvilRange(Cell::new(false)), "");
611 assert_eq!(Ok(""), str::from_utf8(s.as_bytes()));
615 fn test_extend_ref() {
616 let mut a = "foo".to_string();
617 a.extend(&['b', 'a', 'r']);
619 assert_eq!(&a, "foobar");
623 fn test_into_boxed_str() {
624 let xs = String::from("hello my name is bob");
625 let ys = xs.into_boxed_str();
626 assert_eq!(&*ys, "hello my name is bob");
630 fn test_reserve_exact() {
631 // This is all the same as test_reserve
633 let mut s = String::new();
634 assert_eq!(s.capacity(), 0);
637 assert!(s.capacity() >= 2);
643 assert!(s.capacity() >= 16);
645 assert!(s.capacity() >= 32);
650 assert!(s.capacity() >= 33)
654 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
655 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
656 fn test_try_reserve() {
657 // These are the interesting cases:
658 // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
659 // * > isize::MAX should always fail
660 // * On 16/32-bit should CapacityOverflow
661 // * On 64-bit should OOM
662 // * overflow may trigger when adding `len` to `cap` (in number of elements)
663 // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
665 const MAX_CAP: usize = isize::MAX as usize;
666 const MAX_USIZE: usize = usize::MAX;
668 // On 16/32-bit, we check that allocations don't exceed isize::MAX,
669 // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
670 // Any platform that succeeds for these requests is technically broken with
671 // ptr::offset because LLVM is the worst.
672 let guards_against_isize = usize::BITS < 64;
675 // Note: basic stuff is checked by test_reserve
676 let mut empty_string: String = String::new();
678 // Check isize::MAX doesn't count as an overflow
679 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
680 panic!("isize::MAX shouldn't trigger an overflow!");
682 // Play it again, frank! (just to be sure)
683 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
684 panic!("isize::MAX shouldn't trigger an overflow!");
687 if guards_against_isize {
688 // Check isize::MAX + 1 does count as overflow
689 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) {
691 panic!("isize::MAX + 1 should trigger an overflow!")
694 // Check usize::MAX does count as overflow
695 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) {
697 panic!("usize::MAX should trigger an overflow!")
700 // Check isize::MAX + 1 is an OOM
701 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
703 panic!("isize::MAX + 1 should trigger an OOM!")
706 // Check usize::MAX is an OOM
707 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
709 panic!("usize::MAX should trigger an OOM!")
715 // Same basic idea, but with non-zero len
716 let mut ten_bytes: String = String::from("0123456789");
718 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
719 panic!("isize::MAX shouldn't trigger an overflow!");
721 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
722 panic!("isize::MAX shouldn't trigger an overflow!");
724 if guards_against_isize {
725 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
727 panic!("isize::MAX + 1 should trigger an overflow!");
730 if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
732 panic!("isize::MAX + 1 should trigger an OOM!")
735 // Should always overflow in the add-to-len
736 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
738 panic!("usize::MAX should trigger an overflow!")
744 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
745 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
746 fn test_try_reserve_exact() {
747 // This is exactly the same as test_try_reserve with the method changed.
748 // See that test for comments.
750 const MAX_CAP: usize = isize::MAX as usize;
751 const MAX_USIZE: usize = usize::MAX;
753 let guards_against_isize = usize::BITS < 64;
756 let mut empty_string: String = String::new();
758 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
759 panic!("isize::MAX shouldn't trigger an overflow!");
761 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
762 panic!("isize::MAX shouldn't trigger an overflow!");
765 if guards_against_isize {
766 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
768 panic!("isize::MAX + 1 should trigger an overflow!")
771 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
773 panic!("usize::MAX should trigger an overflow!")
776 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
778 panic!("isize::MAX + 1 should trigger an OOM!")
781 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
783 panic!("usize::MAX should trigger an OOM!")
789 let mut ten_bytes: String = String::from("0123456789");
791 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
792 panic!("isize::MAX shouldn't trigger an overflow!");
794 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
795 panic!("isize::MAX shouldn't trigger an overflow!");
797 if guards_against_isize {
798 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
800 panic!("isize::MAX + 1 should trigger an overflow!");
803 if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
805 panic!("isize::MAX + 1 should trigger an OOM!")
808 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
810 panic!("usize::MAX should trigger an overflow!")
816 fn test_from_char() {
817 assert_eq!(String::from('a'), 'a'.to_string());
818 let s: String = 'x'.into();
819 assert_eq!(s, 'x'.to_string());
823 fn test_str_concat() {
824 let a: String = "hello".to_string();
825 let b: String = "world".to_string();
826 let s: String = format!("{}{}", a, b);
827 assert_eq!(s.as_bytes()[9], 'd' as u8);