diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index b6123264ea8db..7422c8113226d 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -139,6 +139,112 @@ pub trait AsciiExt { /// ``` #[unstable(feature = "ascii", issue = "27809")] fn make_ascii_lowercase(&mut self); + + /// Converts this type to its ASCII upper case, + /// consuming the value to avoid allocating memory where `to_ascii_uppercase` would. + /// + /// See `to_ascii_uppercase` for more information. + /// + /// # Examples + /// + /// ``` + /// #![feature(ascii)] + /// + /// use std::ascii::AsciiExt; + /// + /// let ascii: String = "a".to_owned(); + /// + /// let upper = ascii.into_ascii_uppercase(); + /// + /// assert_eq!(upper, "A"); + /// ``` + #[unstable(feature = "ascii", issue = "27809")] + fn into_ascii_uppercase(self) -> Self::Owned where Self: Sized { + self.to_ascii_uppercase() + } + + /// Converts this type to its ASCII lower case, + /// consuming the value to avoid allocating memory where `to_ascii_lowercase` would. + /// + /// See `to_ascii_lowercase` for more information. + /// + /// # Examples + /// + /// ``` + /// #![feature(ascii)] + /// + /// use std::ascii::AsciiExt; + /// + /// let ascii: String = "A".to_owned(); + /// + /// let lower = ascii.into_ascii_lowercase(); + /// + /// assert_eq!(lower, "a"); + /// ``` + #[unstable(feature = "ascii", issue = "27809")] + fn into_ascii_lowercase(self) -> Self::Owned where Self: Sized { + self.to_ascii_lowercase() + } +} + +/// Implement `into_ascii_lowercase` and `into_ascii_uppercase` without memory allocation, +/// defer other methods to `str`. +#[unstable(feature = "ascii", issue = "27809")] +impl AsciiExt for String { + type Owned = Self; + + #[inline] fn is_ascii(&self) -> bool { (**self).is_ascii() } + #[inline] fn to_ascii_uppercase(&self) -> Self { (**self).to_ascii_uppercase() } + #[inline] fn to_ascii_lowercase(&self) -> Self { (**self).to_ascii_lowercase() } + #[inline] fn eq_ignore_ascii_case(&self, o: &Self) -> bool { (**self).eq_ignore_ascii_case(o) } + #[inline] fn make_ascii_uppercase(&mut self) { (**self).make_ascii_uppercase() } + #[inline] fn make_ascii_lowercase(&mut self) { (**self).make_ascii_lowercase() } + + fn into_ascii_lowercase(mut self) -> Self { + unsafe { + for byte in self.as_mut_vec() { + *byte = byte.to_ascii_lowercase() + } + } + self + } + + fn into_ascii_uppercase(mut self) -> Self { + unsafe { + for byte in self.as_mut_vec() { + *byte = byte.to_ascii_uppercase() + } + } + self + } +} + +/// Implement `into_ascii_lowercase` and `into_ascii_uppercase` without memory allocation, +/// defer other methods to `[u8]`. +#[unstable(feature = "ascii", issue = "27809")] +impl AsciiExt for Vec { + type Owned = Self; + + #[inline] fn is_ascii(&self) -> bool { (**self).is_ascii() } + #[inline] fn to_ascii_uppercase(&self) -> Self { (**self).to_ascii_uppercase() } + #[inline] fn to_ascii_lowercase(&self) -> Self { (**self).to_ascii_lowercase() } + #[inline] fn eq_ignore_ascii_case(&self, o: &Self) -> bool { (**self).eq_ignore_ascii_case(o) } + #[inline] fn make_ascii_uppercase(&mut self) { (**self).make_ascii_uppercase() } + #[inline] fn make_ascii_lowercase(&mut self) { (**self).make_ascii_lowercase() } + + fn into_ascii_lowercase(mut self) -> Self { + for byte in &mut self { + *byte = byte.to_ascii_lowercase() + } + self + } + + fn into_ascii_uppercase(mut self) -> Self { + for byte in &mut self { + *byte = byte.to_ascii_uppercase() + } + self + } } #[stable(feature = "rust1", since = "1.0.0")]