1#![stable(feature = "rust1", since = "1.0.0")]
44
45use core::error::Error;
46use core::iter::FusedIterator;
47#[cfg(not(no_global_oom_handling))]
48use core::iter::from_fn;
49#[cfg(not(no_global_oom_handling))]
50use core::ops::Add;
51#[cfg(not(no_global_oom_handling))]
52use core::ops::AddAssign;
53#[cfg(not(no_global_oom_handling))]
54use core::ops::Bound::{Excluded, Included, Unbounded};
55use core::ops::{self, Range, RangeBounds};
56use core::str::pattern::{Pattern, Utf8Pattern};
57use core::{fmt, hash, ptr, slice};
58
59#[cfg(not(no_global_oom_handling))]
60use crate::alloc::Allocator;
61#[cfg(not(no_global_oom_handling))]
62use crate::borrow::{Cow, ToOwned};
63use crate::boxed::Box;
64use crate::collections::TryReserveError;
65use crate::str::{self, CharIndices, Chars, Utf8Error, from_utf8_unchecked_mut};
66#[cfg(not(no_global_oom_handling))]
67use crate::str::{FromStr, from_boxed_utf8_unchecked};
68use crate::vec::{self, Vec};
69
70#[derive(PartialEq, PartialOrd, Eq, Ord)]
358#[stable(feature = "rust1", since = "1.0.0")]
359#[lang = "String"]
360pub struct String {
361 vec: Vec<u8>,
362}
363
364#[stable(feature = "rust1", since = "1.0.0")]
396#[cfg_attr(not(no_global_oom_handling), derive(Clone))]
397#[derive(Debug, PartialEq, Eq)]
398pub struct FromUtf8Error {
399 bytes: Vec<u8>,
400 error: Utf8Error,
401}
402
403#[stable(feature = "rust1", since = "1.0.0")]
419#[derive(Debug)]
420pub struct FromUtf16Error(());
421
422impl String {
423 #[inline]
440 #[rustc_const_stable(feature = "const_string_new", since = "1.39.0")]
441 #[rustc_diagnostic_item = "string_new"]
442 #[stable(feature = "rust1", since = "1.0.0")]
443 #[must_use]
444 pub const fn new() -> String {
445 String { vec: Vec::new() }
446 }
447
448 #[cfg(not(no_global_oom_handling))]
484 #[inline]
485 #[stable(feature = "rust1", since = "1.0.0")]
486 #[must_use]
487 pub fn with_capacity(capacity: usize) -> String {
488 String { vec: Vec::with_capacity(capacity) }
489 }
490
491 #[inline]
499 #[unstable(feature = "try_with_capacity", issue = "91913")]
500 pub fn try_with_capacity(capacity: usize) -> Result<String, TryReserveError> {
501 Ok(String { vec: Vec::try_with_capacity(capacity)? })
502 }
503
504 #[inline]
561 #[stable(feature = "rust1", since = "1.0.0")]
562 #[rustc_diagnostic_item = "string_from_utf8"]
563 pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
564 match str::from_utf8(&vec) {
565 Ok(..) => Ok(String { vec }),
566 Err(e) => Err(FromUtf8Error { bytes: vec, error: e }),
567 }
568 }
569
570 #[must_use]
620 #[cfg(not(no_global_oom_handling))]
621 #[stable(feature = "rust1", since = "1.0.0")]
622 pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
623 let mut iter = v.utf8_chunks();
624
625 let first_valid = if let Some(chunk) = iter.next() {
626 let valid = chunk.valid();
627 if chunk.invalid().is_empty() {
628 debug_assert_eq!(valid.len(), v.len());
629 return Cow::Borrowed(valid);
630 }
631 valid
632 } else {
633 return Cow::Borrowed("");
634 };
635
636 const REPLACEMENT: &str = "\u{FFFD}";
637
638 let mut res = String::with_capacity(v.len());
639 res.push_str(first_valid);
640 res.push_str(REPLACEMENT);
641
642 for chunk in iter {
643 res.push_str(chunk.valid());
644 if !chunk.invalid().is_empty() {
645 res.push_str(REPLACEMENT);
646 }
647 }
648
649 Cow::Owned(res)
650 }
651
652 #[must_use]
687 #[cfg(not(no_global_oom_handling))]
688 #[unstable(feature = "string_from_utf8_lossy_owned", issue = "129436")]
689 pub fn from_utf8_lossy_owned(v: Vec<u8>) -> String {
690 if let Cow::Owned(string) = String::from_utf8_lossy(&v) {
691 string
692 } else {
693 unsafe { String::from_utf8_unchecked(v) }
699 }
700 }
701
702 #[cfg(not(no_global_oom_handling))]
720 #[stable(feature = "rust1", since = "1.0.0")]
721 pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
722 let mut ret = String::with_capacity(v.len());
725 for c in char::decode_utf16(v.iter().cloned()) {
726 if let Ok(c) = c {
727 ret.push(c);
728 } else {
729 return Err(FromUtf16Error(()));
730 }
731 }
732 Ok(ret)
733 }
734
735 #[cfg(not(no_global_oom_handling))]
758 #[must_use]
759 #[inline]
760 #[stable(feature = "rust1", since = "1.0.0")]
761 pub fn from_utf16_lossy(v: &[u16]) -> String {
762 char::decode_utf16(v.iter().cloned())
763 .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
764 .collect()
765 }
766
767 #[cfg(not(no_global_oom_handling))]
788 #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
789 pub fn from_utf16le(v: &[u8]) -> Result<String, FromUtf16Error> {
790 let (chunks, []) = v.as_chunks::<2>() else {
791 return Err(FromUtf16Error(()));
792 };
793 match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
794 (true, ([], v, [])) => Self::from_utf16(v),
795 _ => char::decode_utf16(chunks.iter().copied().map(u16::from_le_bytes))
796 .collect::<Result<_, _>>()
797 .map_err(|_| FromUtf16Error(())),
798 }
799 }
800
801 #[cfg(not(no_global_oom_handling))]
827 #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
828 pub fn from_utf16le_lossy(v: &[u8]) -> String {
829 match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
830 (true, ([], v, [])) => Self::from_utf16_lossy(v),
831 (true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
832 _ => {
833 let (chunks, remainder) = v.as_chunks::<2>();
834 let string = char::decode_utf16(chunks.iter().copied().map(u16::from_le_bytes))
835 .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
836 .collect();
837 if remainder.is_empty() { string } else { string + "\u{FFFD}" }
838 }
839 }
840 }
841
842 #[cfg(not(no_global_oom_handling))]
863 #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
864 pub fn from_utf16be(v: &[u8]) -> Result<String, FromUtf16Error> {
865 let (chunks, []) = v.as_chunks::<2>() else {
866 return Err(FromUtf16Error(()));
867 };
868 match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
869 (true, ([], v, [])) => Self::from_utf16(v),
870 _ => char::decode_utf16(chunks.iter().copied().map(u16::from_be_bytes))
871 .collect::<Result<_, _>>()
872 .map_err(|_| FromUtf16Error(())),
873 }
874 }
875
876 #[cfg(not(no_global_oom_handling))]
902 #[unstable(feature = "str_from_utf16_endian", issue = "116258")]
903 pub fn from_utf16be_lossy(v: &[u8]) -> String {
904 match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
905 (true, ([], v, [])) => Self::from_utf16_lossy(v),
906 (true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
907 _ => {
908 let (chunks, remainder) = v.as_chunks::<2>();
909 let string = char::decode_utf16(chunks.iter().copied().map(u16::from_be_bytes))
910 .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
911 .collect();
912 if remainder.is_empty() { string } else { string + "\u{FFFD}" }
913 }
914 }
915 }
916
917 #[must_use = "losing the pointer will leak memory"]
944 #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
945 pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
946 self.vec.into_raw_parts()
947 }
948
949 #[inline]
993 #[stable(feature = "rust1", since = "1.0.0")]
994 pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String {
995 unsafe { String { vec: Vec::from_raw_parts(buf, length, capacity) } }
996 }
997
998 #[inline]
1025 #[must_use]
1026 #[stable(feature = "rust1", since = "1.0.0")]
1027 pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
1028 String { vec: bytes }
1029 }
1030
1031 #[inline]
1044 #[must_use = "`self` will be dropped if the result is not used"]
1045 #[stable(feature = "rust1", since = "1.0.0")]
1046 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1047 #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
1048 pub const fn into_bytes(self) -> Vec<u8> {
1049 self.vec
1050 }
1051
1052 #[inline]
1062 #[must_use]
1063 #[stable(feature = "string_as_str", since = "1.7.0")]
1064 #[rustc_diagnostic_item = "string_as_str"]
1065 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1066 pub const fn as_str(&self) -> &str {
1067 unsafe { str::from_utf8_unchecked(self.vec.as_slice()) }
1070 }
1071
1072 #[inline]
1085 #[must_use]
1086 #[stable(feature = "string_as_str", since = "1.7.0")]
1087 #[rustc_diagnostic_item = "string_as_mut_str"]
1088 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1089 pub const fn as_mut_str(&mut self) -> &mut str {
1090 unsafe { str::from_utf8_unchecked_mut(self.vec.as_mut_slice()) }
1093 }
1094
1095 #[cfg(not(no_global_oom_handling))]
1107 #[inline]
1108 #[track_caller]
1109 #[stable(feature = "rust1", since = "1.0.0")]
1110 #[rustc_confusables("append", "push")]
1111 #[rustc_diagnostic_item = "string_push_str"]
1112 pub fn push_str(&mut self, string: &str) {
1113 self.vec.extend_from_slice(string.as_bytes())
1114 }
1115
1116 #[cfg(not(no_global_oom_handling))]
1138 #[stable(feature = "string_extend_from_within", since = "1.87.0")]
1139 #[track_caller]
1140 pub fn extend_from_within<R>(&mut self, src: R)
1141 where
1142 R: RangeBounds<usize>,
1143 {
1144 let src @ Range { start, end } = slice::range(src, ..self.len());
1145
1146 assert!(self.is_char_boundary(start));
1147 assert!(self.is_char_boundary(end));
1148
1149 self.vec.extend_from_within(src);
1150 }
1151
1152 #[inline]
1162 #[must_use]
1163 #[stable(feature = "rust1", since = "1.0.0")]
1164 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1165 pub const fn capacity(&self) -> usize {
1166 self.vec.capacity()
1167 }
1168
1169 #[cfg(not(no_global_oom_handling))]
1210 #[inline]
1211 #[track_caller]
1212 #[stable(feature = "rust1", since = "1.0.0")]
1213 pub fn reserve(&mut self, additional: usize) {
1214 self.vec.reserve(additional)
1215 }
1216
1217 #[cfg(not(no_global_oom_handling))]
1261 #[inline]
1262 #[stable(feature = "rust1", since = "1.0.0")]
1263 #[track_caller]
1264 pub fn reserve_exact(&mut self, additional: usize) {
1265 self.vec.reserve_exact(additional)
1266 }
1267
1268 #[stable(feature = "try_reserve", since = "1.57.0")]
1299 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
1300 self.vec.try_reserve(additional)
1301 }
1302
1303 #[stable(feature = "try_reserve", since = "1.57.0")]
1340 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
1341 self.vec.try_reserve_exact(additional)
1342 }
1343
1344 #[cfg(not(no_global_oom_handling))]
1358 #[inline]
1359 #[track_caller]
1360 #[stable(feature = "rust1", since = "1.0.0")]
1361 pub fn shrink_to_fit(&mut self) {
1362 self.vec.shrink_to_fit()
1363 }
1364
1365 #[cfg(not(no_global_oom_handling))]
1386 #[inline]
1387 #[track_caller]
1388 #[stable(feature = "shrink_to", since = "1.56.0")]
1389 pub fn shrink_to(&mut self, min_capacity: usize) {
1390 self.vec.shrink_to(min_capacity)
1391 }
1392
1393 #[cfg(not(no_global_oom_handling))]
1407 #[inline]
1408 #[stable(feature = "rust1", since = "1.0.0")]
1409 #[track_caller]
1410 pub fn push(&mut self, ch: char) {
1411 let len = self.len();
1412 let ch_len = ch.len_utf8();
1413 self.reserve(ch_len);
1414
1415 unsafe {
1417 core::char::encode_utf8_raw_unchecked(ch as u32, self.vec.as_mut_ptr().add(self.len()));
1418 self.vec.set_len(len + ch_len);
1419 }
1420 }
1421
1422 #[inline]
1436 #[must_use]
1437 #[stable(feature = "rust1", since = "1.0.0")]
1438 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1439 pub const fn as_bytes(&self) -> &[u8] {
1440 self.vec.as_slice()
1441 }
1442
1443 #[inline]
1465 #[stable(feature = "rust1", since = "1.0.0")]
1466 #[track_caller]
1467 pub fn truncate(&mut self, new_len: usize) {
1468 if new_len <= self.len() {
1469 assert!(self.is_char_boundary(new_len));
1470 self.vec.truncate(new_len)
1471 }
1472 }
1473
1474 #[inline]
1490 #[stable(feature = "rust1", since = "1.0.0")]
1491 pub fn pop(&mut self) -> Option<char> {
1492 let ch = self.chars().rev().next()?;
1493 let newlen = self.len() - ch.len_utf8();
1494 unsafe {
1495 self.vec.set_len(newlen);
1496 }
1497 Some(ch)
1498 }
1499
1500 #[inline]
1521 #[stable(feature = "rust1", since = "1.0.0")]
1522 #[track_caller]
1523 #[rustc_confusables("delete", "take")]
1524 pub fn remove(&mut self, idx: usize) -> char {
1525 let ch = match self[idx..].chars().next() {
1526 Some(ch) => ch,
1527 None => panic!("cannot remove a char from the end of a string"),
1528 };
1529
1530 let next = idx + ch.len_utf8();
1531 let len = self.len();
1532 unsafe {
1533 ptr::copy(self.vec.as_ptr().add(next), self.vec.as_mut_ptr().add(idx), len - next);
1534 self.vec.set_len(len - (next - idx));
1535 }
1536 ch
1537 }
1538
1539 #[cfg(not(no_global_oom_handling))]
1560 #[unstable(feature = "string_remove_matches", reason = "new API", issue = "72826")]
1561 pub fn remove_matches<P: Pattern>(&mut self, pat: P) {
1562 use core::str::pattern::Searcher;
1563
1564 let rejections = {
1565 let mut searcher = pat.into_searcher(self);
1566 let mut front = 0;
1576 let rejections: Vec<_> = from_fn(|| {
1577 let (start, end) = searcher.next_match()?;
1578 let prev_front = front;
1579 front = end;
1580 Some((prev_front, start))
1581 })
1582 .collect();
1583 rejections.into_iter().chain(core::iter::once((front, self.len())))
1584 };
1585
1586 let mut len = 0;
1587 let ptr = self.vec.as_mut_ptr();
1588
1589 for (start, end) in rejections {
1590 let count = end - start;
1591 if start != len {
1592 unsafe {
1599 ptr::copy(ptr.add(start), ptr.add(len), count);
1600 }
1601 }
1602 len += count;
1603 }
1604
1605 unsafe {
1606 self.vec.set_len(len);
1607 }
1608 }
1609
1610 #[inline]
1637 #[stable(feature = "string_retain", since = "1.26.0")]
1638 pub fn retain<F>(&mut self, mut f: F)
1639 where
1640 F: FnMut(char) -> bool,
1641 {
1642 struct SetLenOnDrop<'a> {
1643 s: &'a mut String,
1644 idx: usize,
1645 del_bytes: usize,
1646 }
1647
1648 impl<'a> Drop for SetLenOnDrop<'a> {
1649 fn drop(&mut self) {
1650 let new_len = self.idx - self.del_bytes;
1651 debug_assert!(new_len <= self.s.len());
1652 unsafe { self.s.vec.set_len(new_len) };
1653 }
1654 }
1655
1656 let len = self.len();
1657 let mut guard = SetLenOnDrop { s: self, idx: 0, del_bytes: 0 };
1658
1659 while guard.idx < len {
1660 let ch =
1661 unsafe { guard.s.get_unchecked(guard.idx..len).chars().next().unwrap_unchecked() };
1665 let ch_len = ch.len_utf8();
1666
1667 if !f(ch) {
1668 guard.del_bytes += ch_len;
1669 } else if guard.del_bytes > 0 {
1670 ch.encode_utf8(unsafe {
1677 crate::slice::from_raw_parts_mut(
1678 guard.s.as_mut_ptr().add(guard.idx - guard.del_bytes),
1679 ch.len_utf8(),
1680 )
1681 });
1682 }
1683
1684 guard.idx += ch_len;
1686 }
1687
1688 drop(guard);
1689 }
1690
1691 #[cfg(not(no_global_oom_handling))]
1716 #[inline]
1717 #[track_caller]
1718 #[stable(feature = "rust1", since = "1.0.0")]
1719 #[rustc_confusables("set")]
1720 pub fn insert(&mut self, idx: usize, ch: char) {
1721 assert!(self.is_char_boundary(idx));
1722
1723 let len = self.len();
1724 let ch_len = ch.len_utf8();
1725 self.reserve(ch_len);
1726
1727 unsafe {
1731 ptr::copy(
1732 self.vec.as_ptr().add(idx),
1733 self.vec.as_mut_ptr().add(idx + ch_len),
1734 len - idx,
1735 );
1736 }
1737
1738 unsafe {
1741 core::char::encode_utf8_raw_unchecked(ch as u32, self.vec.as_mut_ptr().add(idx));
1742 }
1743
1744 unsafe {
1746 self.vec.set_len(len + ch_len);
1747 }
1748 }
1749
1750 #[cfg(not(no_global_oom_handling))]
1773 #[inline]
1774 #[track_caller]
1775 #[stable(feature = "insert_str", since = "1.16.0")]
1776 #[rustc_diagnostic_item = "string_insert_str"]
1777 pub fn insert_str(&mut self, idx: usize, string: &str) {
1778 assert!(self.is_char_boundary(idx));
1779
1780 let len = self.len();
1781 let amt = string.len();
1782 self.reserve(amt);
1783
1784 unsafe {
1788 ptr::copy(self.vec.as_ptr().add(idx), self.vec.as_mut_ptr().add(idx + amt), len - idx);
1789 }
1790
1791 unsafe {
1795 ptr::copy_nonoverlapping(string.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
1796 }
1797
1798 unsafe {
1800 self.vec.set_len(len + amt);
1801 }
1802 }
1803
1804 #[inline]
1828 #[stable(feature = "rust1", since = "1.0.0")]
1829 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1830 pub const unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
1831 &mut self.vec
1832 }
1833
1834 #[inline]
1849 #[must_use]
1850 #[stable(feature = "rust1", since = "1.0.0")]
1851 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1852 #[rustc_confusables("length", "size")]
1853 #[rustc_no_implicit_autorefs]
1854 pub const fn len(&self) -> usize {
1855 self.vec.len()
1856 }
1857
1858 #[inline]
1870 #[must_use]
1871 #[stable(feature = "rust1", since = "1.0.0")]
1872 #[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1873 #[rustc_no_implicit_autorefs]
1874 pub const fn is_empty(&self) -> bool {
1875 self.len() == 0
1876 }
1877
1878 #[cfg(not(no_global_oom_handling))]
1902 #[inline]
1903 #[track_caller]
1904 #[stable(feature = "string_split_off", since = "1.16.0")]
1905 #[must_use = "use `.truncate()` if you don't need the other half"]
1906 pub fn split_off(&mut self, at: usize) -> String {
1907 assert!(self.is_char_boundary(at));
1908 let other = self.vec.split_off(at);
1909 unsafe { String::from_utf8_unchecked(other) }
1910 }
1911
1912 #[inline]
1929 #[stable(feature = "rust1", since = "1.0.0")]
1930 pub fn clear(&mut self) {
1931 self.vec.clear()
1932 }
1933
1934 #[stable(feature = "drain", since = "1.6.0")]
1968 #[track_caller]
1969 pub fn drain<R>(&mut self, range: R) -> Drain<'_>
1970 where
1971 R: RangeBounds<usize>,
1972 {
1973 let Range { start, end } = slice::range(range, ..self.len());
1980 assert!(self.is_char_boundary(start));
1981 assert!(self.is_char_boundary(end));
1982
1983 let self_ptr = self as *mut _;
1986 let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
1988
1989 Drain { start, end, iter: chars_iter, string: self_ptr }
1990 }
1991
1992 #[inline]
2041 #[must_use = "`self` will be dropped if the result is not used"]
2042 #[unstable(feature = "string_into_chars", issue = "133125")]
2043 pub fn into_chars(self) -> IntoChars {
2044 IntoChars { bytes: self.into_bytes().into_iter() }
2045 }
2046
2047 #[cfg(not(no_global_oom_handling))]
2067 #[stable(feature = "splice", since = "1.27.0")]
2068 #[track_caller]
2069 pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
2070 where
2071 R: RangeBounds<usize>,
2072 {
2073 let start = range.start_bound();
2080 match start {
2081 Included(&n) => assert!(self.is_char_boundary(n)),
2082 Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
2083 Unbounded => {}
2084 };
2085 let end = range.end_bound();
2087 match end {
2088 Included(&n) => assert!(self.is_char_boundary(n + 1)),
2089 Excluded(&n) => assert!(self.is_char_boundary(n)),
2090 Unbounded => {}
2091 };
2092
2093 unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
2097 }
2098
2099 #[cfg(not(no_global_oom_handling))]
2115 #[stable(feature = "box_str", since = "1.4.0")]
2116 #[must_use = "`self` will be dropped if the result is not used"]
2117 #[inline]
2118 #[track_caller]
2119 pub fn into_boxed_str(self) -> Box<str> {
2120 let slice = self.vec.into_boxed_slice();
2121 unsafe { from_boxed_utf8_unchecked(slice) }
2122 }
2123
2124 #[stable(feature = "string_leak", since = "1.72.0")]
2149 #[inline]
2150 pub fn leak<'a>(self) -> &'a mut str {
2151 let slice = self.vec.leak();
2152 unsafe { from_utf8_unchecked_mut(slice) }
2153 }
2154}
2155
2156impl FromUtf8Error {
2157 #[must_use]
2170 #[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")]
2171 pub fn as_bytes(&self) -> &[u8] {
2172 &self.bytes[..]
2173 }
2174
2175 #[must_use]
2193 #[cfg(not(no_global_oom_handling))]
2194 #[unstable(feature = "string_from_utf8_lossy_owned", issue = "129436")]
2195 pub fn into_utf8_lossy(self) -> String {
2196 const REPLACEMENT: &str = "\u{FFFD}";
2197
2198 let mut res = {
2199 let mut v = Vec::with_capacity(self.bytes.len());
2200
2201 v.extend_from_slice(&self.bytes[..self.error.valid_up_to()]);
2204
2205 unsafe { String::from_utf8_unchecked(v) }
2209 };
2210
2211 let iter = self.bytes[self.error.valid_up_to()..].utf8_chunks();
2212
2213 for chunk in iter {
2214 res.push_str(chunk.valid());
2215 if !chunk.invalid().is_empty() {
2216 res.push_str(REPLACEMENT);
2217 }
2218 }
2219
2220 res
2221 }
2222
2223 #[must_use = "`self` will be dropped if the result is not used"]
2240 #[stable(feature = "rust1", since = "1.0.0")]
2241 pub fn into_bytes(self) -> Vec<u8> {
2242 self.bytes
2243 }
2244
2245 #[must_use]
2267 #[stable(feature = "rust1", since = "1.0.0")]
2268 pub fn utf8_error(&self) -> Utf8Error {
2269 self.error
2270 }
2271}
2272
2273#[stable(feature = "rust1", since = "1.0.0")]
2274impl fmt::Display for FromUtf8Error {
2275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2276 fmt::Display::fmt(&self.error, f)
2277 }
2278}
2279
2280#[stable(feature = "rust1", since = "1.0.0")]
2281impl fmt::Display for FromUtf16Error {
2282 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2283 fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
2284 }
2285}
2286
2287#[stable(feature = "rust1", since = "1.0.0")]
2288impl Error for FromUtf8Error {
2289 #[allow(deprecated)]
2290 fn description(&self) -> &str {
2291 "invalid utf-8"
2292 }
2293}
2294
2295#[stable(feature = "rust1", since = "1.0.0")]
2296impl Error for FromUtf16Error {
2297 #[allow(deprecated)]
2298 fn description(&self) -> &str {
2299 "invalid utf-16"
2300 }
2301}
2302
2303#[cfg(not(no_global_oom_handling))]
2304#[stable(feature = "rust1", since = "1.0.0")]
2305impl Clone for String {
2306 #[track_caller]
2307 fn clone(&self) -> Self {
2308 String { vec: self.vec.clone() }
2309 }
2310
2311 #[track_caller]
2316 fn clone_from(&mut self, source: &Self) {
2317 self.vec.clone_from(&source.vec);
2318 }
2319}
2320
2321#[cfg(not(no_global_oom_handling))]
2322#[stable(feature = "rust1", since = "1.0.0")]
2323impl FromIterator<char> for String {
2324 fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String {
2325 let mut buf = String::new();
2326 buf.extend(iter);
2327 buf
2328 }
2329}
2330
2331#[cfg(not(no_global_oom_handling))]
2332#[stable(feature = "string_from_iter_by_ref", since = "1.17.0")]
2333impl<'a> FromIterator<&'a char> for String {
2334 fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> String {
2335 let mut buf = String::new();
2336 buf.extend(iter);
2337 buf
2338 }
2339}
2340
2341#[cfg(not(no_global_oom_handling))]
2342#[stable(feature = "rust1", since = "1.0.0")]
2343impl<'a> FromIterator<&'a str> for String {
2344 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> String {
2345 let mut buf = String::new();
2346 buf.extend(iter);
2347 buf
2348 }
2349}
2350
2351#[cfg(not(no_global_oom_handling))]
2352#[stable(feature = "extend_string", since = "1.4.0")]
2353impl FromIterator<String> for String {
2354 fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String {
2355 let mut iterator = iter.into_iter();
2356
2357 match iterator.next() {
2361 None => String::new(),
2362 Some(mut buf) => {
2363 buf.extend(iterator);
2364 buf
2365 }
2366 }
2367 }
2368}
2369
2370#[cfg(not(no_global_oom_handling))]
2371#[stable(feature = "box_str2", since = "1.45.0")]
2372impl<A: Allocator> FromIterator<Box<str, A>> for String {
2373 fn from_iter<I: IntoIterator<Item = Box<str, A>>>(iter: I) -> String {
2374 let mut buf = String::new();
2375 buf.extend(iter);
2376 buf
2377 }
2378}
2379
2380#[cfg(not(no_global_oom_handling))]
2381#[stable(feature = "herd_cows", since = "1.19.0")]
2382impl<'a> FromIterator<Cow<'a, str>> for String {
2383 fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> String {
2384 let mut iterator = iter.into_iter();
2385
2386 match iterator.next() {
2390 None => String::new(),
2391 Some(cow) => {
2392 let mut buf = cow.into_owned();
2393 buf.extend(iterator);
2394 buf
2395 }
2396 }
2397 }
2398}
2399
2400#[cfg(not(no_global_oom_handling))]
2401#[stable(feature = "rust1", since = "1.0.0")]
2402impl Extend<char> for String {
2403 fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
2404 let iterator = iter.into_iter();
2405 let (lower_bound, _) = iterator.size_hint();
2406 self.reserve(lower_bound);
2407 iterator.for_each(move |c| self.push(c));
2408 }
2409
2410 #[inline]
2411 fn extend_one(&mut self, c: char) {
2412 self.push(c);
2413 }
2414
2415 #[inline]
2416 fn extend_reserve(&mut self, additional: usize) {
2417 self.reserve(additional);
2418 }
2419}
2420
2421#[cfg(not(no_global_oom_handling))]
2422#[stable(feature = "extend_ref", since = "1.2.0")]
2423impl<'a> Extend<&'a char> for String {
2424 fn extend<I: IntoIterator<Item = &'a char>>(&mut self, iter: I) {
2425 self.extend(iter.into_iter().cloned());
2426 }
2427
2428 #[inline]
2429 fn extend_one(&mut self, &c: &'a char) {
2430 self.push(c);
2431 }
2432
2433 #[inline]
2434 fn extend_reserve(&mut self, additional: usize) {
2435 self.reserve(additional);
2436 }
2437}
2438
2439#[cfg(not(no_global_oom_handling))]
2440#[stable(feature = "rust1", since = "1.0.0")]
2441impl<'a> Extend<&'a str> for String {
2442 fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iter: I) {
2443 iter.into_iter().for_each(move |s| self.push_str(s));
2444 }
2445
2446 #[inline]
2447 fn extend_one(&mut self, s: &'a str) {
2448 self.push_str(s);
2449 }
2450}
2451
2452#[cfg(not(no_global_oom_handling))]
2453#[stable(feature = "box_str2", since = "1.45.0")]
2454impl<A: Allocator> Extend<Box<str, A>> for String {
2455 fn extend<I: IntoIterator<Item = Box<str, A>>>(&mut self, iter: I) {
2456 iter.into_iter().for_each(move |s| self.push_str(&s));
2457 }
2458}
2459
2460#[cfg(not(no_global_oom_handling))]
2461#[stable(feature = "extend_string", since = "1.4.0")]
2462impl Extend<String> for String {
2463 fn extend<I: IntoIterator<Item = String>>(&mut self, iter: I) {
2464 iter.into_iter().for_each(move |s| self.push_str(&s));
2465 }
2466
2467 #[inline]
2468 fn extend_one(&mut self, s: String) {
2469 self.push_str(&s);
2470 }
2471}
2472
2473#[cfg(not(no_global_oom_handling))]
2474#[stable(feature = "herd_cows", since = "1.19.0")]
2475impl<'a> Extend<Cow<'a, str>> for String {
2476 fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {
2477 iter.into_iter().for_each(move |s| self.push_str(&s));
2478 }
2479
2480 #[inline]
2481 fn extend_one(&mut self, s: Cow<'a, str>) {
2482 self.push_str(&s);
2483 }
2484}
2485
2486#[cfg(not(no_global_oom_handling))]
2487#[unstable(feature = "ascii_char", issue = "110998")]
2488impl Extend<core::ascii::Char> for String {
2489 #[inline]
2490 #[track_caller]
2491 fn extend<I: IntoIterator<Item = core::ascii::Char>>(&mut self, iter: I) {
2492 self.vec.extend(iter.into_iter().map(|c| c.to_u8()));
2493 }
2494
2495 #[inline]
2496 #[track_caller]
2497 fn extend_one(&mut self, c: core::ascii::Char) {
2498 self.vec.push(c.to_u8());
2499 }
2500}
2501
2502#[cfg(not(no_global_oom_handling))]
2503#[unstable(feature = "ascii_char", issue = "110998")]
2504impl<'a> Extend<&'a core::ascii::Char> for String {
2505 #[inline]
2506 #[track_caller]
2507 fn extend<I: IntoIterator<Item = &'a core::ascii::Char>>(&mut self, iter: I) {
2508 self.extend(iter.into_iter().cloned());
2509 }
2510
2511 #[inline]
2512 #[track_caller]
2513 fn extend_one(&mut self, c: &'a core::ascii::Char) {
2514 self.vec.push(c.to_u8());
2515 }
2516}
2517
2518#[unstable(
2526 feature = "pattern",
2527 reason = "API not fully fleshed out and ready to be stabilized",
2528 issue = "27721"
2529)]
2530impl<'b> Pattern for &'b String {
2531 type Searcher<'a> = <&'b str as Pattern>::Searcher<'a>;
2532
2533 fn into_searcher(self, haystack: &str) -> <&'b str as Pattern>::Searcher<'_> {
2534 self[..].into_searcher(haystack)
2535 }
2536
2537 #[inline]
2538 fn is_contained_in(self, haystack: &str) -> bool {
2539 self[..].is_contained_in(haystack)
2540 }
2541
2542 #[inline]
2543 fn is_prefix_of(self, haystack: &str) -> bool {
2544 self[..].is_prefix_of(haystack)
2545 }
2546
2547 #[inline]
2548 fn strip_prefix_of(self, haystack: &str) -> Option<&str> {
2549 self[..].strip_prefix_of(haystack)
2550 }
2551
2552 #[inline]
2553 fn is_suffix_of<'a>(self, haystack: &'a str) -> bool
2554 where
2555 Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
2556 {
2557 self[..].is_suffix_of(haystack)
2558 }
2559
2560 #[inline]
2561 fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
2562 where
2563 Self::Searcher<'a>: core::str::pattern::ReverseSearcher<'a>,
2564 {
2565 self[..].strip_suffix_of(haystack)
2566 }
2567
2568 #[inline]
2569 fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>> {
2570 Some(Utf8Pattern::StringPattern(self.as_bytes()))
2571 }
2572}
2573
2574macro_rules! impl_eq {
2575 ($lhs:ty, $rhs: ty) => {
2576 #[stable(feature = "rust1", since = "1.0.0")]
2577 #[allow(unused_lifetimes)]
2578 impl<'a, 'b> PartialEq<$rhs> for $lhs {
2579 #[inline]
2580 fn eq(&self, other: &$rhs) -> bool {
2581 PartialEq::eq(&self[..], &other[..])
2582 }
2583 #[inline]
2584 fn ne(&self, other: &$rhs) -> bool {
2585 PartialEq::ne(&self[..], &other[..])
2586 }
2587 }
2588
2589 #[stable(feature = "rust1", since = "1.0.0")]
2590 #[allow(unused_lifetimes)]
2591 impl<'a, 'b> PartialEq<$lhs> for $rhs {
2592 #[inline]
2593 fn eq(&self, other: &$lhs) -> bool {
2594 PartialEq::eq(&self[..], &other[..])
2595 }
2596 #[inline]
2597 fn ne(&self, other: &$lhs) -> bool {
2598 PartialEq::ne(&self[..], &other[..])
2599 }
2600 }
2601 };
2602}
2603
2604impl_eq! { String, str }
2605impl_eq! { String, &'a str }
2606#[cfg(not(no_global_oom_handling))]
2607impl_eq! { Cow<'a, str>, str }
2608#[cfg(not(no_global_oom_handling))]
2609impl_eq! { Cow<'a, str>, &'b str }
2610#[cfg(not(no_global_oom_handling))]
2611impl_eq! { Cow<'a, str>, String }
2612
2613#[stable(feature = "rust1", since = "1.0.0")]
2614#[rustc_const_unstable(feature = "const_default", issue = "143894")]
2615impl const Default for String {
2616 #[inline]
2618 fn default() -> String {
2619 String::new()
2620 }
2621}
2622
2623#[stable(feature = "rust1", since = "1.0.0")]
2624impl fmt::Display for String {
2625 #[inline]
2626 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2627 fmt::Display::fmt(&**self, f)
2628 }
2629}
2630
2631#[stable(feature = "rust1", since = "1.0.0")]
2632impl fmt::Debug for String {
2633 #[inline]
2634 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2635 fmt::Debug::fmt(&**self, f)
2636 }
2637}
2638
2639#[stable(feature = "rust1", since = "1.0.0")]
2640impl hash::Hash for String {
2641 #[inline]
2642 fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
2643 (**self).hash(hasher)
2644 }
2645}
2646
2647#[cfg(not(no_global_oom_handling))]
2685#[stable(feature = "rust1", since = "1.0.0")]
2686impl Add<&str> for String {
2687 type Output = String;
2688
2689 #[inline]
2690 fn add(mut self, other: &str) -> String {
2691 self.push_str(other);
2692 self
2693 }
2694}
2695
2696#[cfg(not(no_global_oom_handling))]
2700#[stable(feature = "stringaddassign", since = "1.12.0")]
2701impl AddAssign<&str> for String {
2702 #[inline]
2703 fn add_assign(&mut self, other: &str) {
2704 self.push_str(other);
2705 }
2706}
2707
2708#[stable(feature = "rust1", since = "1.0.0")]
2709impl<I> ops::Index<I> for String
2710where
2711 I: slice::SliceIndex<str>,
2712{
2713 type Output = I::Output;
2714
2715 #[inline]
2716 fn index(&self, index: I) -> &I::Output {
2717 index.index(self.as_str())
2718 }
2719}
2720
2721#[stable(feature = "rust1", since = "1.0.0")]
2722impl<I> ops::IndexMut<I> for String
2723where
2724 I: slice::SliceIndex<str>,
2725{
2726 #[inline]
2727 fn index_mut(&mut self, index: I) -> &mut I::Output {
2728 index.index_mut(self.as_mut_str())
2729 }
2730}
2731
2732#[stable(feature = "rust1", since = "1.0.0")]
2733impl ops::Deref for String {
2734 type Target = str;
2735
2736 #[inline]
2737 fn deref(&self) -> &str {
2738 self.as_str()
2739 }
2740}
2741
2742#[unstable(feature = "deref_pure_trait", issue = "87121")]
2743unsafe impl ops::DerefPure for String {}
2744
2745#[stable(feature = "derefmut_for_string", since = "1.3.0")]
2746impl ops::DerefMut for String {
2747 #[inline]
2748 fn deref_mut(&mut self) -> &mut str {
2749 self.as_mut_str()
2750 }
2751}
2752
2753#[stable(feature = "str_parse_error", since = "1.5.0")]
2759pub type ParseError = core::convert::Infallible;
2760
2761#[cfg(not(no_global_oom_handling))]
2762#[stable(feature = "rust1", since = "1.0.0")]
2763impl FromStr for String {
2764 type Err = core::convert::Infallible;
2765 #[inline]
2766 fn from_str(s: &str) -> Result<String, Self::Err> {
2767 Ok(String::from(s))
2768 }
2769}
2770
2771#[rustc_diagnostic_item = "ToString"]
2780#[stable(feature = "rust1", since = "1.0.0")]
2781pub trait ToString {
2782 #[rustc_conversion_suggestion]
2793 #[stable(feature = "rust1", since = "1.0.0")]
2794 #[rustc_diagnostic_item = "to_string_method"]
2795 fn to_string(&self) -> String;
2796}
2797
2798#[cfg(not(no_global_oom_handling))]
2805#[stable(feature = "rust1", since = "1.0.0")]
2806impl<T: fmt::Display + ?Sized> ToString for T {
2807 #[inline]
2808 fn to_string(&self) -> String {
2809 <Self as SpecToString>::spec_to_string(self)
2810 }
2811}
2812
2813#[cfg(not(no_global_oom_handling))]
2814trait SpecToString {
2815 fn spec_to_string(&self) -> String;
2816}
2817
2818#[cfg(not(no_global_oom_handling))]
2819impl<T: fmt::Display + ?Sized> SpecToString for T {
2820 #[inline]
2825 default fn spec_to_string(&self) -> String {
2826 let mut buf = String::new();
2827 let mut formatter =
2828 core::fmt::Formatter::new(&mut buf, core::fmt::FormattingOptions::new());
2829 fmt::Display::fmt(self, &mut formatter)
2831 .expect("a Display implementation returned an error unexpectedly");
2832 buf
2833 }
2834}
2835
2836#[cfg(not(no_global_oom_handling))]
2837impl SpecToString for core::ascii::Char {
2838 #[inline]
2839 fn spec_to_string(&self) -> String {
2840 self.as_str().to_owned()
2841 }
2842}
2843
2844#[cfg(not(no_global_oom_handling))]
2845impl SpecToString for char {
2846 #[inline]
2847 fn spec_to_string(&self) -> String {
2848 String::from(self.encode_utf8(&mut [0; char::MAX_LEN_UTF8]))
2849 }
2850}
2851
2852#[cfg(not(no_global_oom_handling))]
2853impl SpecToString for bool {
2854 #[inline]
2855 fn spec_to_string(&self) -> String {
2856 String::from(if *self { "true" } else { "false" })
2857 }
2858}
2859
2860macro_rules! impl_to_string {
2861 ($($signed:ident, $unsigned:ident,)*) => {
2862 $(
2863 #[cfg(not(no_global_oom_handling))]
2864 #[cfg(not(feature = "optimize_for_size"))]
2865 impl SpecToString for $signed {
2866 #[inline]
2867 fn spec_to_string(&self) -> String {
2868 const SIZE: usize = $signed::MAX.ilog10() as usize + 1;
2869 let mut buf = [core::mem::MaybeUninit::<u8>::uninit(); SIZE];
2870 let mut out;
2872 if *self < 0 {
2873 out = String::with_capacity(SIZE + 1);
2874 out.push('-');
2875 } else {
2876 out = String::with_capacity(SIZE);
2877 }
2878
2879 unsafe { out.push_str(self.unsigned_abs()._fmt(&mut buf)); }
2881 out
2882 }
2883 }
2884 #[cfg(not(no_global_oom_handling))]
2885 #[cfg(not(feature = "optimize_for_size"))]
2886 impl SpecToString for $unsigned {
2887 #[inline]
2888 fn spec_to_string(&self) -> String {
2889 const SIZE: usize = $unsigned::MAX.ilog10() as usize + 1;
2890 let mut buf = [core::mem::MaybeUninit::<u8>::uninit(); SIZE];
2891
2892 unsafe { self._fmt(&mut buf).to_string() }
2894 }
2895 }
2896 )*
2897 }
2898}
2899
2900impl_to_string! {
2901 i8, u8,
2902 i16, u16,
2903 i32, u32,
2904 i64, u64,
2905 isize, usize,
2906 i128, u128,
2907}
2908
2909#[cfg(not(no_global_oom_handling))]
2910#[cfg(feature = "optimize_for_size")]
2911impl SpecToString for u8 {
2912 #[inline]
2913 fn spec_to_string(&self) -> String {
2914 let mut buf = String::with_capacity(3);
2915 let mut n = *self;
2916 if n >= 10 {
2917 if n >= 100 {
2918 buf.push((b'0' + n / 100) as char);
2919 n %= 100;
2920 }
2921 buf.push((b'0' + n / 10) as char);
2922 n %= 10;
2923 }
2924 buf.push((b'0' + n) as char);
2925 buf
2926 }
2927}
2928
2929#[cfg(not(no_global_oom_handling))]
2930#[cfg(feature = "optimize_for_size")]
2931impl SpecToString for i8 {
2932 #[inline]
2933 fn spec_to_string(&self) -> String {
2934 let mut buf = String::with_capacity(4);
2935 if self.is_negative() {
2936 buf.push('-');
2937 }
2938 let mut n = self.unsigned_abs();
2939 if n >= 10 {
2940 if n >= 100 {
2941 buf.push('1');
2942 n -= 100;
2943 }
2944 buf.push((b'0' + n / 10) as char);
2945 n %= 10;
2946 }
2947 buf.push((b'0' + n) as char);
2948 buf
2949 }
2950}
2951
2952#[cfg(not(no_global_oom_handling))]
2957macro_rules! to_string_str_wrap_in_ref {
2958 {x $($x:ident)*} => {
2959 &to_string_str_wrap_in_ref! { $($x)* }
2960 };
2961 {} => { str };
2962}
2963#[cfg(not(no_global_oom_handling))]
2964macro_rules! to_string_expr_wrap_in_deref {
2965 {$self:expr ; x $($x:ident)*} => {
2966 *(to_string_expr_wrap_in_deref! { $self ; $($x)* })
2967 };
2968 {$self:expr ;} => { $self };
2969}
2970#[cfg(not(no_global_oom_handling))]
2971macro_rules! to_string_str {
2972 {$($($x:ident)*),+} => {
2973 $(
2974 impl SpecToString for to_string_str_wrap_in_ref!($($x)*) {
2975 #[inline]
2976 fn spec_to_string(&self) -> String {
2977 String::from(to_string_expr_wrap_in_deref!(self ; $($x)*))
2978 }
2979 }
2980 )+
2981 };
2982}
2983
2984#[cfg(not(no_global_oom_handling))]
2985to_string_str! {
2986 x x x x x x x x x x x x,
2987 x x x x x x x x x x x,
2988 x x x x x x x x x x,
2989 x x x x x x x x x,
2990 x x x x x x x x,
2991 x x x x x x x,
2992 x x x x x x,
2993 x x x x x,
2994 x x x x,
2995 x x x,
2996 x x,
2997 x,
2998}
2999
3000#[cfg(not(no_global_oom_handling))]
3001impl SpecToString for Cow<'_, str> {
3002 #[inline]
3003 fn spec_to_string(&self) -> String {
3004 self[..].to_owned()
3005 }
3006}
3007
3008#[cfg(not(no_global_oom_handling))]
3009impl SpecToString for String {
3010 #[inline]
3011 fn spec_to_string(&self) -> String {
3012 self.to_owned()
3013 }
3014}
3015
3016#[cfg(not(no_global_oom_handling))]
3017impl SpecToString for fmt::Arguments<'_> {
3018 #[inline]
3019 fn spec_to_string(&self) -> String {
3020 crate::fmt::format(*self)
3021 }
3022}
3023
3024#[stable(feature = "rust1", since = "1.0.0")]
3025impl AsRef<str> for String {
3026 #[inline]
3027 fn as_ref(&self) -> &str {
3028 self
3029 }
3030}
3031
3032#[stable(feature = "string_as_mut", since = "1.43.0")]
3033impl AsMut<str> for String {
3034 #[inline]
3035 fn as_mut(&mut self) -> &mut str {
3036 self
3037 }
3038}
3039
3040#[stable(feature = "rust1", since = "1.0.0")]
3041impl AsRef<[u8]> for String {
3042 #[inline]
3043 fn as_ref(&self) -> &[u8] {
3044 self.as_bytes()
3045 }
3046}
3047
3048#[cfg(not(no_global_oom_handling))]
3049#[stable(feature = "rust1", since = "1.0.0")]
3050impl From<&str> for String {
3051 #[inline]
3055 fn from(s: &str) -> String {
3056 s.to_owned()
3057 }
3058}
3059
3060#[cfg(not(no_global_oom_handling))]
3061#[stable(feature = "from_mut_str_for_string", since = "1.44.0")]
3062impl From<&mut str> for String {
3063 #[inline]
3067 fn from(s: &mut str) -> String {
3068 s.to_owned()
3069 }
3070}
3071
3072#[cfg(not(no_global_oom_handling))]
3073#[stable(feature = "from_ref_string", since = "1.35.0")]
3074impl From<&String> for String {
3075 #[inline]
3079 fn from(s: &String) -> String {
3080 s.clone()
3081 }
3082}
3083
3084#[stable(feature = "string_from_box", since = "1.18.0")]
3086impl From<Box<str>> for String {
3087 fn from(s: Box<str>) -> String {
3100 s.into_string()
3101 }
3102}
3103
3104#[cfg(not(no_global_oom_handling))]
3105#[stable(feature = "box_from_str", since = "1.20.0")]
3106impl From<String> for Box<str> {
3107 fn from(s: String) -> Box<str> {
3119 s.into_boxed_str()
3120 }
3121}
3122
3123#[cfg(not(no_global_oom_handling))]
3124#[stable(feature = "string_from_cow_str", since = "1.14.0")]
3125impl<'a> From<Cow<'a, str>> for String {
3126 fn from(s: Cow<'a, str>) -> String {
3143 s.into_owned()
3144 }
3145}
3146
3147#[cfg(not(no_global_oom_handling))]
3148#[stable(feature = "rust1", since = "1.0.0")]
3149impl<'a> From<&'a str> for Cow<'a, str> {
3150 #[inline]
3163 fn from(s: &'a str) -> Cow<'a, str> {
3164 Cow::Borrowed(s)
3165 }
3166}
3167
3168#[cfg(not(no_global_oom_handling))]
3169#[stable(feature = "rust1", since = "1.0.0")]
3170impl<'a> From<String> for Cow<'a, str> {
3171 #[inline]
3186 fn from(s: String) -> Cow<'a, str> {
3187 Cow::Owned(s)
3188 }
3189}
3190
3191#[cfg(not(no_global_oom_handling))]
3192#[stable(feature = "cow_from_string_ref", since = "1.28.0")]
3193impl<'a> From<&'a String> for Cow<'a, str> {
3194 #[inline]
3208 fn from(s: &'a String) -> Cow<'a, str> {
3209 Cow::Borrowed(s.as_str())
3210 }
3211}
3212
3213#[cfg(not(no_global_oom_handling))]
3214#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
3215impl<'a> FromIterator<char> for Cow<'a, str> {
3216 fn from_iter<I: IntoIterator<Item = char>>(it: I) -> Cow<'a, str> {
3217 Cow::Owned(FromIterator::from_iter(it))
3218 }
3219}
3220
3221#[cfg(not(no_global_oom_handling))]
3222#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
3223impl<'a, 'b> FromIterator<&'b str> for Cow<'a, str> {
3224 fn from_iter<I: IntoIterator<Item = &'b str>>(it: I) -> Cow<'a, str> {
3225 Cow::Owned(FromIterator::from_iter(it))
3226 }
3227}
3228
3229#[cfg(not(no_global_oom_handling))]
3230#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
3231impl<'a> FromIterator<String> for Cow<'a, str> {
3232 fn from_iter<I: IntoIterator<Item = String>>(it: I) -> Cow<'a, str> {
3233 Cow::Owned(FromIterator::from_iter(it))
3234 }
3235}
3236
3237#[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
3238impl From<String> for Vec<u8> {
3239 fn from(string: String) -> Vec<u8> {
3252 string.into_bytes()
3253 }
3254}
3255
3256#[stable(feature = "try_from_vec_u8_for_string", since = "1.87.0")]
3257impl TryFrom<Vec<u8>> for String {
3258 type Error = FromUtf8Error;
3259 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
3270 Self::from_utf8(bytes)
3271 }
3272}
3273
3274#[cfg(not(no_global_oom_handling))]
3275#[stable(feature = "rust1", since = "1.0.0")]
3276impl fmt::Write for String {
3277 #[inline]
3278 fn write_str(&mut self, s: &str) -> fmt::Result {
3279 self.push_str(s);
3280 Ok(())
3281 }
3282
3283 #[inline]
3284 fn write_char(&mut self, c: char) -> fmt::Result {
3285 self.push(c);
3286 Ok(())
3287 }
3288}
3289
3290#[cfg_attr(not(no_global_oom_handling), derive(Clone))]
3298#[must_use = "iterators are lazy and do nothing unless consumed"]
3299#[unstable(feature = "string_into_chars", issue = "133125")]
3300pub struct IntoChars {
3301 bytes: vec::IntoIter<u8>,
3302}
3303
3304#[unstable(feature = "string_into_chars", issue = "133125")]
3305impl fmt::Debug for IntoChars {
3306 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3307 f.debug_tuple("IntoChars").field(&self.as_str()).finish()
3308 }
3309}
3310
3311impl IntoChars {
3312 #[unstable(feature = "string_into_chars", issue = "133125")]
3329 #[must_use]
3330 #[inline]
3331 pub fn as_str(&self) -> &str {
3332 unsafe { str::from_utf8_unchecked(self.bytes.as_slice()) }
3334 }
3335
3336 #[cfg(not(no_global_oom_handling))]
3351 #[unstable(feature = "string_into_chars", issue = "133125")]
3352 #[inline]
3353 pub fn into_string(self) -> String {
3354 unsafe { String::from_utf8_unchecked(self.bytes.collect()) }
3356 }
3357
3358 #[inline]
3359 fn iter(&self) -> CharIndices<'_> {
3360 self.as_str().char_indices()
3361 }
3362}
3363
3364#[unstable(feature = "string_into_chars", issue = "133125")]
3365impl Iterator for IntoChars {
3366 type Item = char;
3367
3368 #[inline]
3369 fn next(&mut self) -> Option<char> {
3370 let mut iter = self.iter();
3371 match iter.next() {
3372 None => None,
3373 Some((_, ch)) => {
3374 let offset = iter.offset();
3375 let _ = self.bytes.advance_by(offset);
3377 Some(ch)
3378 }
3379 }
3380 }
3381
3382 #[inline]
3383 fn count(self) -> usize {
3384 self.iter().count()
3385 }
3386
3387 #[inline]
3388 fn size_hint(&self) -> (usize, Option<usize>) {
3389 self.iter().size_hint()
3390 }
3391
3392 #[inline]
3393 fn last(mut self) -> Option<char> {
3394 self.next_back()
3395 }
3396}
3397
3398#[unstable(feature = "string_into_chars", issue = "133125")]
3399impl DoubleEndedIterator for IntoChars {
3400 #[inline]
3401 fn next_back(&mut self) -> Option<char> {
3402 let len = self.as_str().len();
3403 let mut iter = self.iter();
3404 match iter.next_back() {
3405 None => None,
3406 Some((idx, ch)) => {
3407 let _ = self.bytes.advance_back_by(len - idx);
3409 Some(ch)
3410 }
3411 }
3412 }
3413}
3414
3415#[unstable(feature = "string_into_chars", issue = "133125")]
3416impl FusedIterator for IntoChars {}
3417
3418#[stable(feature = "drain", since = "1.6.0")]
3425pub struct Drain<'a> {
3426 string: *mut String,
3428 start: usize,
3430 end: usize,
3432 iter: Chars<'a>,
3434}
3435
3436#[stable(feature = "collection_debug", since = "1.17.0")]
3437impl fmt::Debug for Drain<'_> {
3438 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3439 f.debug_tuple("Drain").field(&self.as_str()).finish()
3440 }
3441}
3442
3443#[stable(feature = "drain", since = "1.6.0")]
3444unsafe impl Sync for Drain<'_> {}
3445#[stable(feature = "drain", since = "1.6.0")]
3446unsafe impl Send for Drain<'_> {}
3447
3448#[stable(feature = "drain", since = "1.6.0")]
3449impl Drop for Drain<'_> {
3450 fn drop(&mut self) {
3451 unsafe {
3452 let self_vec = (*self.string).as_mut_vec();
3455 if self.start <= self.end && self.end <= self_vec.len() {
3456 self_vec.drain(self.start..self.end);
3457 }
3458 }
3459 }
3460}
3461
3462impl<'a> Drain<'a> {
3463 #[must_use]
3475 #[stable(feature = "string_drain_as_str", since = "1.55.0")]
3476 pub fn as_str(&self) -> &str {
3477 self.iter.as_str()
3478 }
3479}
3480
3481#[stable(feature = "string_drain_as_str", since = "1.55.0")]
3482impl<'a> AsRef<str> for Drain<'a> {
3483 fn as_ref(&self) -> &str {
3484 self.as_str()
3485 }
3486}
3487
3488#[stable(feature = "string_drain_as_str", since = "1.55.0")]
3489impl<'a> AsRef<[u8]> for Drain<'a> {
3490 fn as_ref(&self) -> &[u8] {
3491 self.as_str().as_bytes()
3492 }
3493}
3494
3495#[stable(feature = "drain", since = "1.6.0")]
3496impl Iterator for Drain<'_> {
3497 type Item = char;
3498
3499 #[inline]
3500 fn next(&mut self) -> Option<char> {
3501 self.iter.next()
3502 }
3503
3504 fn size_hint(&self) -> (usize, Option<usize>) {
3505 self.iter.size_hint()
3506 }
3507
3508 #[inline]
3509 fn last(mut self) -> Option<char> {
3510 self.next_back()
3511 }
3512}
3513
3514#[stable(feature = "drain", since = "1.6.0")]
3515impl DoubleEndedIterator for Drain<'_> {
3516 #[inline]
3517 fn next_back(&mut self) -> Option<char> {
3518 self.iter.next_back()
3519 }
3520}
3521
3522#[stable(feature = "fused", since = "1.26.0")]
3523impl FusedIterator for Drain<'_> {}
3524
3525#[cfg(not(no_global_oom_handling))]
3526#[stable(feature = "from_char_for_string", since = "1.46.0")]
3527impl From<char> for String {
3528 #[inline]
3537 fn from(c: char) -> Self {
3538 c.to_string()
3539 }
3540}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4