2 use std::collections::TryReserveError::*;
4 use std::{isize, usize};
6 pub trait IntoCow<'a, B: ?Sized>
10 fn into_cow(self) -> Cow<'a, B>;
13 impl<'a> IntoCow<'a, str> for String {
14 fn into_cow(self) -> Cow<'a, str> {
19 impl<'a> IntoCow<'a, str> for &'a str {
20 fn into_cow(self) -> Cow<'a, str> {
27 let owned: Option<std::string::String> = "string".parse().ok();
28 assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
32 fn test_from_cow_str() {
33 assert_eq!(String::from(Cow::Borrowed("string")), "string");
34 assert_eq!(String::from(Cow::Owned(String::from("string"))), "string");
38 fn test_unsized_to_string() {
40 let _: String = (*s).to_string();
45 let xs = b"hello".to_vec();
46 assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello"));
48 let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
49 assert_eq!(String::from_utf8(xs).unwrap(), String::from("ศไทย中华Việt Nam"));
51 let xs = b"hello\xFF".to_vec();
52 let err = String::from_utf8(xs).unwrap_err();
53 assert_eq!(err.as_bytes(), b"hello\xff");
54 let err_clone = err.clone();
55 assert_eq!(err, err_clone);
56 assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
57 assert_eq!(err_clone.utf8_error().valid_up_to(), 5);
61 fn test_from_utf8_lossy() {
63 let ys: Cow<'_, str> = "hello".into_cow();
64 assert_eq!(String::from_utf8_lossy(xs), ys);
66 let xs = "ศไทย中华Việt Nam".as_bytes();
67 let ys: Cow<'_, str> = "ศไทย中华Việt Nam".into_cow();
68 assert_eq!(String::from_utf8_lossy(xs), ys);
70 let xs = b"Hello\xC2 There\xFF Goodbye";
72 String::from_utf8_lossy(xs),
73 String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow()
76 let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
78 String::from_utf8_lossy(xs),
79 String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow()
82 let xs = b"\xF5foo\xF5\x80bar";
84 String::from_utf8_lossy(xs),
85 String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow()
88 let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
90 String::from_utf8_lossy(xs),
91 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow()
94 let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
96 String::from_utf8_lossy(xs),
97 String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow()
100 let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
102 String::from_utf8_lossy(xs),
103 String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow()
107 let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
109 String::from_utf8_lossy(xs),
110 String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow()
115 fn test_from_utf16() {
118 String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
120 0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, 0xdf39,
121 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a,
125 String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
127 0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, 0xdc32,
128 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, 0xdc4d, 0x000a,
132 String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
134 0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, 0xdf11,
135 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, 0xdf15, 0xd800,
136 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, 0x000a,
140 String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
142 0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801, 0xdc9b,
143 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020, 0xd801, 0xdc88,
144 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f, 0xd801, 0xdc9c, 0xd801,
145 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc86,
149 // Issue #12318, even-numbered non-BMP planes
150 (String::from("\u{20000}"), vec![0xD840, 0xDC00]),
154 let (s, u) = (*p).clone();
155 let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
156 let u_as_string = String::from_utf16(&u).unwrap();
158 assert!(core::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
159 assert_eq!(s_as_utf16, u);
161 assert_eq!(u_as_string, s);
162 assert_eq!(String::from_utf16_lossy(&u), s);
164 assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
165 assert_eq!(u_as_string.encode_utf16().collect::<Vec<u16>>(), u);
170 fn test_utf16_invalid() {
171 // completely positive cases tested above.
173 assert!(String::from_utf16(&[0xD800]).is_err());
175 assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
178 assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
181 assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
185 fn test_from_utf16_lossy() {
186 // completely positive cases tested above.
188 assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from("\u{FFFD}"));
190 assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]), String::from("\u{FFFD}\u{FFFD}"));
193 assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from("a\u{FFFD}"));
197 String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
198 String::from("\u{FFFD}𐒋\u{FFFD}")
203 fn test_push_bytes() {
204 let mut s = String::from("ABC");
206 let mv = s.as_mut_vec();
207 mv.extend_from_slice(&[b'D']);
209 assert_eq!(s, "ABCD");
214 let mut s = String::new();
216 assert_eq!(&s[0..], "");
218 assert_eq!(&s[0..], "abc");
219 s.push_str("ประเทศไทย中华Việt Nam");
220 assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
224 fn test_add_assign() {
225 let mut s = String::new();
227 assert_eq!(s.as_str(), "");
229 assert_eq!(s.as_str(), "abc");
230 s += "ประเทศไทย中华Việt Nam";
231 assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
236 let mut data = String::from("ประเทศไทย中");
238 data.push('b'); // 1 byte
239 data.push('¢'); // 2 byte
240 data.push('€'); // 3 byte
241 data.push('𤭢'); // 4 byte
242 assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
247 let mut data = String::from("ประเทศไทย中华b¢€𤭢");
248 assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
249 assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
250 assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
251 assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
252 assert_eq!(data.pop().unwrap(), '华');
253 assert_eq!(data, "ประเทศไทย中");
257 fn test_split_off_empty() {
258 let orig = "Hello, world!";
259 let mut split = String::from(orig);
260 let empty: String = split.split_off(orig.len());
261 assert!(empty.is_empty());
266 fn test_split_off_past_end() {
267 let orig = "Hello, world!";
268 let mut split = String::from(orig);
269 split.split_off(orig.len() + 1);
274 fn test_split_off_mid_char() {
275 let mut orig = String::from("山");
280 fn test_split_off_ascii() {
281 let mut ab = String::from("ABCD");
282 let cd = ab.split_off(2);
283 assert_eq!(ab, "AB");
284 assert_eq!(cd, "CD");
288 fn test_split_off_unicode() {
289 let mut nihon = String::from("日本語");
290 let go = nihon.split_off("日本".len());
291 assert_eq!(nihon, "日本");
296 fn test_str_truncate() {
297 let mut s = String::from("12345");
299 assert_eq!(s, "12345");
301 assert_eq!(s, "123");
305 let mut s = String::from("12345");
314 fn test_str_truncate_invalid_len() {
315 let mut s = String::from("12345");
317 assert_eq!(s, "12345");
322 fn test_str_truncate_split_codepoint() {
323 let mut s = String::from("\u{FC}"); // ü
328 fn test_str_clear() {
329 let mut s = String::from("12345");
331 assert_eq!(s.len(), 0);
337 let a = String::from("12345");
340 assert_eq!(b.len(), 7);
341 assert_eq!(b, "1234522");
346 let mut s = "ศไทย中华Việt Nam; foobar".to_string();
347 assert_eq!(s.remove(0), 'ศ');
348 assert_eq!(s.len(), 33);
349 assert_eq!(s, "ไทย中华Việt Nam; foobar");
350 assert_eq!(s.remove(17), 'ệ');
351 assert_eq!(s, "ไทย中华Vit Nam; foobar");
357 "ศ".to_string().remove(1);
362 let mut s = String::from("α_β_γ");
365 assert_eq!(s, "α_β_γ");
367 s.retain(|c| c != '_');
368 assert_eq!(s, "αβγ");
370 s.retain(|c| c != 'β');
373 s.retain(|c| c == 'α');
382 let mut s = "foobar".to_string();
384 assert_eq!(s, "ệfoobar");
386 assert_eq!(s, "ệfooยbar");
392 "".to_string().insert(1, 't');
397 "ệ".to_string().insert(1, 't');
402 let s = "foobar".to_string();
403 assert_eq!("foobar", &s[..]);
404 assert_eq!("foo", &s[..3]);
405 assert_eq!("bar", &s[3..]);
406 assert_eq!("oob", &s[1..4]);
410 fn test_simple_types() {
411 assert_eq!(1.to_string(), "1");
412 assert_eq!((-1).to_string(), "-1");
413 assert_eq!(200.to_string(), "200");
414 assert_eq!(2.to_string(), "2");
415 assert_eq!(true.to_string(), "true");
416 assert_eq!(false.to_string(), "false");
417 assert_eq!(("hi".to_string()).to_string(), "hi");
422 let x: Vec<i32> = vec![];
423 assert_eq!(format!("{:?}", x), "[]");
424 assert_eq!(format!("{:?}", vec![1]), "[1]");
425 assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
426 assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
430 fn test_from_iterator() {
431 let s = "ศไทย中华Việt Nam".to_string();
435 let a: String = s.chars().collect();
438 let mut b = t.to_string();
442 let c: String = vec![t, u].into_iter().collect();
445 let mut d = t.to_string();
452 let mut s = String::from("αβγ");
453 assert_eq!(s.drain(2..4).collect::<String>(), "β");
456 let mut t = String::from("abcd");
458 assert_eq!(t, "abcd");
460 assert_eq!(t, "bcd");
462 assert_eq!(t, "bcd");
468 fn test_replace_range() {
469 let mut s = "Hello, world!".to_owned();
470 s.replace_range(7..12, "世界");
471 assert_eq!(s, "Hello, 世界!");
476 fn test_replace_range_char_boundary() {
477 let mut s = "Hello, 世界!".to_owned();
478 s.replace_range(..8, "");
482 fn test_replace_range_inclusive_range() {
483 let mut v = String::from("12345");
484 v.replace_range(2..=3, "789");
485 assert_eq!(v, "127895");
486 v.replace_range(1..=2, "A");
487 assert_eq!(v, "1A895");
492 fn test_replace_range_out_of_bounds() {
493 let mut s = String::from("12345");
494 s.replace_range(5..6, "789");
499 fn test_replace_range_inclusive_out_of_bounds() {
500 let mut s = String::from("12345");
501 s.replace_range(5..=5, "789");
505 fn test_replace_range_empty() {
506 let mut s = String::from("12345");
507 s.replace_range(1..2, "");
508 assert_eq!(s, "1345");
512 fn test_replace_range_unbounded() {
513 let mut s = String::from("12345");
514 s.replace_range(.., "");
519 fn test_extend_ref() {
520 let mut a = "foo".to_string();
521 a.extend(&['b', 'a', 'r']);
523 assert_eq!(&a, "foobar");
527 fn test_into_boxed_str() {
528 let xs = String::from("hello my name is bob");
529 let ys = xs.into_boxed_str();
530 assert_eq!(&*ys, "hello my name is bob");
534 fn test_reserve_exact() {
535 // This is all the same as test_reserve
537 let mut s = String::new();
538 assert_eq!(s.capacity(), 0);
541 assert!(s.capacity() >= 2);
547 assert!(s.capacity() >= 16);
549 assert!(s.capacity() >= 32);
554 assert!(s.capacity() >= 33)
558 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
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 fn test_try_reserve_exact() {
649 // This is exactly the same as test_try_reserve with the method changed.
650 // See that test for comments.
652 const MAX_CAP: usize = isize::MAX as usize;
653 const MAX_USIZE: usize = usize::MAX;
655 let guards_against_isize = size_of::<usize>() < 8;
658 let mut empty_string: String = String::new();
660 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
661 panic!("isize::MAX shouldn't trigger an overflow!");
663 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
664 panic!("isize::MAX shouldn't trigger an overflow!");
667 if guards_against_isize {
668 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
670 panic!("isize::MAX + 1 should trigger an overflow!")
673 if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
675 panic!("usize::MAX should trigger an overflow!")
678 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
680 panic!("isize::MAX + 1 should trigger an OOM!")
683 if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
685 panic!("usize::MAX should trigger an OOM!")
691 let mut ten_bytes: String = String::from("0123456789");
693 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
694 panic!("isize::MAX shouldn't trigger an overflow!");
696 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
697 panic!("isize::MAX shouldn't trigger an overflow!");
699 if guards_against_isize {
700 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
702 panic!("isize::MAX + 1 should trigger an overflow!");
705 if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
707 panic!("isize::MAX + 1 should trigger an OOM!")
710 if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
712 panic!("usize::MAX should trigger an overflow!")