From 700ac0e58d48475bf74b3170b497d235fe9e9392 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 1 Feb 2016 01:54:56 +0100 Subject: [PATCH] Add AsciiExt::into_ascii_{upper,lower}case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default implementations (with where Self: Sized) are so that methods that take `self` by value can exist in a trait that’s implemented for dynamically-sized types (`str` and `[u8]`). CC https://github.com/rust-lang/rust/issues/27809#issuecomment-177564950 --- src/libstd/ascii.rs | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) 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")]