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 cd = ab.split_off(2);
282 assert_eq!(ab, "AB");
283 assert_eq!(cd, "CD");
287 fn test_split_off_unicode() {
288 let mut nihon = String::from("日本語");
289 let go = nihon.split_off("日本".len());
290 assert_eq!(nihon, "日本");
295 fn test_str_truncate() {
296 let mut s = String::from("12345");
298 assert_eq!(s, "12345");
300 assert_eq!(s, "123");
304 let mut s = String::from("12345");
313 fn test_str_truncate_invalid_len() {
314 let mut s = String::from("12345");
316 assert_eq!(s, "12345");
321 fn test_str_truncate_split_codepoint() {
322 let mut s = String::from("\u{FC}"); // ü
327 fn test_str_clear() {
328 let mut s = String::from("12345");
330 assert_eq!(s.len(), 0);
336 let a = String::from("12345");
339 assert_eq!(b.len(), 7);
340 assert_eq!(b, "1234522");
345 let mut s = "ศไทย中华Việt Nam; foobar".to_string();
346 assert_eq!(s.remove(0), 'ศ');
347 assert_eq!(s.len(), 33);
348 assert_eq!(s, "ไทย中华Việt Nam; foobar");
349 assert_eq!(s.remove(17), 'ệ');
350 assert_eq!(s, "ไทย中华Vit Nam; foobar");
356 "ศ".to_string().remove(1);
361 let mut s = String::from("α_β_γ");
364 assert_eq!(s, "α_β_γ");
366 s.retain(|c| c != '_');
367 assert_eq!(s, "αβγ");
369 s.retain(|c| c != 'β');
372 s.retain(|c| c == 'α');
381 let mut s = "foobar".to_string();
383 assert_eq!(s, "ệfoobar");
385 assert_eq!(s, "ệfooยbar");
391 "".to_string().insert(1, 't');
396 "ệ".to_string().insert(1, 't');
401 let s = "foobar".to_string();
402 assert_eq!("foobar", &s[..]);
403 assert_eq!("foo", &s[..3]);
404 assert_eq!("bar", &s[3..]);
405 assert_eq!("oob", &s[1..4]);
409 fn test_simple_types() {
410 assert_eq!(1.to_string(), "1");
411 assert_eq!((-1).to_string(), "-1");
412 assert_eq!(200.to_string(), "200");
413 assert_eq!(2.to_string(), "2");
414 assert_eq!(true.to_string(), "true");
415 assert_eq!(false.to_string(), "false");
416 assert_eq!(("hi".to_string()).to_string(), "hi");
421 let x: Vec<i32> = vec![];
422 assert_eq!(format!("{:?}", x), "[]");
423 assert_eq!(format!("{:?}", vec![1]), "[1]");
424 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
425 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
429 fn test_from_iterator() {
430 let s = "ศไทย中华Việt Nam".to_string();
434 let a: String = s.chars().collect();
437 let mut b = t.to_string();
441 let c: String = vec![t, u].into_iter().collect();
444 let mut d = t.to_string();
451 let mut s = String::from("αβγ");
452 assert_eq!(s.drain(2..4).collect::<String>(), "β");
455 let mut t = String::from("abcd");
457 assert_eq!(t, "abcd");
459 assert_eq!(t, "bcd");
461 assert_eq!(t, "bcd");
467 fn test_replace_range() {
468 let mut s = "Hello, world!".to_owned();
469 s.replace_range(7..12, "世界");
470 assert_eq!(s, "Hello, 世界!");
475 fn test_replace_range_char_boundary() {
476 let mut s = "Hello, 世界!".to_owned();
477 s.replace_range(..8, "");
481 fn test_replace_range_inclusive_range() {
482 let mut v = String::from("12345");
483 v.replace_range(2..=3, "789");
484 assert_eq!(v, "127895");
485 v.replace_range(1..=2, "A");
486 assert_eq!(v, "1A895");
491 fn test_replace_range_out_of_bounds() {
492 let mut s = String::from("12345");
493 s.replace_range(5..6, "789");
498 fn test_replace_range_inclusive_out_of_bounds() {
499 let mut s = String::from("12345");
500 s.replace_range(5..=5, "789");
504 fn test_replace_range_empty() {
505 let mut s = String::from("12345");
506 s.replace_range(1..2, "");
507 assert_eq!(s, "1345");
511 fn test_replace_range_unbounded() {
512 let mut s = String::from("12345");
513 s.replace_range(.., "");
518 fn test_extend_ref() {
519 let mut a = "foo".to_string();
520 a.extend(&['b', 'a', 'r']);
522 assert_eq!(&a, "foobar");
526 fn test_into_boxed_str() {
527 let xs = String::from("hello my name is bob");
528 let ys = xs.into_boxed_str();
529 assert_eq!(&*ys, "hello my name is bob");
533 fn test_reserve_exact() {
534 // This is all the same as test_reserve
536 let mut s = String::new();
537 assert_eq!(s.capacity(), 0);
540 assert!(s.capacity() >= 2);
546 assert!(s.capacity() >= 16);
548 assert!(s.capacity() >= 32);
553 assert!(s.capacity() >= 33)
557 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
558 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
559 fn test_try_reserve() {
560 // These are the interesting cases:
561 // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
562 // * > isize::MAX should always fail
563 // * On 16/32-bit should CapacityOverflow
564 // * On 64-bit should OOM
565 // * overflow may trigger when adding `len` to `cap` (in number of elements)
566 // * overflow may trigger when multiplying `new_cap` by size_of::<T> (to get bytes)
568 const MAX_CAP: usize = isize::MAX as usize;
569 const MAX_USIZE: usize = usize::MAX;
571 // On 16/32-bit, we check that allocations don't exceed isize::MAX,
572 // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
573 // Any platform that succeeds for these requests is technically broken with
574 // ptr::offset because LLVM is the worst.
575 let guards_against_isize = size_of::<usize>() < 8;
578 // Note: basic stuff is checked by test_reserve
579 let mut empty_string: String = String::new();
581 // Check isize::MAX doesn't count as an overflow
582 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
583 panic!("isize::MAX shouldn't trigger an overflow!");
585 // Play it again, frank! (just to be sure)
586 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
587 panic!("isize::MAX shouldn't trigger an overflow!");
590 if guards_against_isize {
591 // Check isize::MAX + 1 does count as overflow
592 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) {
594 panic!("isize::MAX + 1 should trigger an overflow!")
597 // Check usize::MAX does count as overflow
598 if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) {
600 panic!("usize::MAX should trigger an overflow!")
603 // Check isize::MAX + 1 is an OOM
604 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
606 panic!("isize::MAX + 1 should trigger an OOM!")
609 // Check usize::MAX is an OOM
610 if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
612 panic!("usize::MAX should trigger an OOM!")
618 // Same basic idea, but with non-zero len
619 let mut ten_bytes: String = String::from("0123456789");
621 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
622 panic!("isize::MAX shouldn't trigger an overflow!");
624 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
625 panic!("isize::MAX shouldn't trigger an overflow!");
627 if guards_against_isize {
628 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
630 panic!("isize::MAX + 1 should trigger an overflow!");
633 if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
635 panic!("isize::MAX + 1 should trigger an OOM!")
638 // Should always overflow in the add-to-len
639 if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
641 panic!("usize::MAX should trigger an overflow!")
647 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
648 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
649 fn test_try_reserve_exact() {
650 // This is exactly the same as test_try_reserve with the method changed.
651 // See that test for comments.
653 const MAX_CAP: usize = isize::MAX as usize;
654 const MAX_USIZE: usize = usize::MAX;
656 let guards_against_isize = size_of::<usize>() < 8;
659 let mut empty_string: String = String::new();
661 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
662 panic!("isize::MAX shouldn't trigger an overflow!");
664 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
665 panic!("isize::MAX shouldn't trigger an overflow!");
668 if guards_against_isize {
669 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
671 panic!("isize::MAX + 1 should trigger an overflow!")
674 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
676 panic!("usize::MAX should trigger an overflow!")
679 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
681 panic!("isize::MAX + 1 should trigger an OOM!")
684 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
686 panic!("usize::MAX should trigger an OOM!")
692 let mut ten_bytes: String = String::from("0123456789");
694 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
695 panic!("isize::MAX shouldn't trigger an overflow!");
697 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
698 panic!("isize::MAX shouldn't trigger an overflow!");
700 if guards_against_isize {
701 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
703 panic!("isize::MAX + 1 should trigger an overflow!");
706 if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
708 panic!("isize::MAX + 1 should trigger an OOM!")
711 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
713 panic!("usize::MAX should trigger an overflow!")
719 fn test_from_char() {
720 assert_eq!(String::from('a'), 'a'.to_string());
721 let s: String = 'x'.into();
722 assert_eq!(s, 'x'.to_string());
726 fn test_str_concat() {
727 let a: String = "hello".to_string();
728 let b: String = "world".to_string();
729 let s: String = format!("{}{}", a, b);
730 assert_eq!(s.as_bytes()[9], 'd' as u8);