Skip to content

Commit

Permalink
Add AsciiExt::into_ascii_{upper,lower}case
Browse files Browse the repository at this point in the history
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 #27809 (comment)
  • Loading branch information
SimonSapin committed Feb 1, 2016
1 parent 9041b93 commit 700ac0e
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions src/libstd/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8> {
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")]
Expand Down

0 comments on commit 700ac0e

Please sign in to comment.