diff options
Diffstat (limited to 'library/alloc/src/string.rs')
| -rw-r--r-- | library/alloc/src/string.rs | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index b29f740ef0f..f10ef1fca13 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -966,11 +966,8 @@ impl String { /// This is highly unsafe, due to the number of invariants that aren't /// checked: /// - /// * The memory at `buf` needs to have been previously allocated by the - /// same allocator the standard library uses, with a required alignment of exactly 1. - /// * `length` needs to be less than or equal to `capacity`. - /// * `capacity` needs to be the correct value. - /// * The first `length` bytes at `buf` need to be valid UTF-8. + /// * all safety requirements for [`Vec::<u8>::from_raw_parts`]. + /// * all safety requirements for [`String::from_utf8_unchecked`]. /// /// Violating these may cause problems like corrupting the allocator's /// internal data structures. For example, it is normally **not** safe to @@ -1419,7 +1416,9 @@ impl String { pub fn push(&mut self, ch: char) { match ch.len_utf8() { 1 => self.vec.push(ch as u8), - _ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()), + _ => { + self.vec.extend_from_slice(ch.encode_utf8(&mut [0; char::MAX_LEN_UTF8]).as_bytes()) + } } } @@ -1716,7 +1715,7 @@ impl String { #[rustc_confusables("set")] pub fn insert(&mut self, idx: usize, ch: char) { assert!(self.is_char_boundary(idx)); - let mut bits = [0; 4]; + let mut bits = [0; char::MAX_LEN_UTF8]; let bits = ch.encode_utf8(&mut bits).as_bytes(); unsafe { @@ -2442,6 +2441,32 @@ impl<'a> Extend<Cow<'a, str>> for String { } } +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "ascii_char", issue = "110998")] +impl Extend<core::ascii::Char> for String { + fn extend<I: IntoIterator<Item = core::ascii::Char>>(&mut self, iter: I) { + self.vec.extend(iter.into_iter().map(|c| c.to_u8())); + } + + #[inline] + fn extend_one(&mut self, c: core::ascii::Char) { + self.vec.push(c.to_u8()); + } +} + +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "ascii_char", issue = "110998")] +impl<'a> Extend<&'a core::ascii::Char> for String { + fn extend<I: IntoIterator<Item = &'a core::ascii::Char>>(&mut self, iter: I) { + self.extend(iter.into_iter().cloned()); + } + + #[inline] + fn extend_one(&mut self, c: &'a core::ascii::Char) { + self.vec.push(c.to_u8()); + } +} + /// A convenience impl that delegates to the impl for `&str`. /// /// # Examples @@ -2771,7 +2796,7 @@ impl SpecToString for core::ascii::Char { impl SpecToString for char { #[inline] fn spec_to_string(&self) -> String { - String::from(self.encode_utf8(&mut [0; 4])) + String::from(self.encode_utf8(&mut [0; char::MAX_LEN_UTF8])) } } @@ -3129,6 +3154,24 @@ impl From<String> for Vec<u8> { } } +#[stable(feature = "try_from_vec_u8_for_string", since = "CURRENT_RUSTC_VERSION")] +impl TryFrom<Vec<u8>> for String { + type Error = FromUtf8Error; + /// Converts the given [`Vec<u8>`] into a [`String`] if it contains valid UTF-8 data. + /// + /// # Examples + /// + /// ``` + /// let s1 = b"hello world".to_vec(); + /// let v1 = String::try_from(s1).unwrap(); + /// assert_eq!(v1, "hello world"); + /// + /// ``` + fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> { + Self::from_utf8(bytes) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Write for String { |
