Skip to content

Commit

Permalink
Rollup merge of rust-lang#111009 - scottmcm:ascii-char, r=BurntSushi
Browse files Browse the repository at this point in the history
Add `ascii::Char` (ACP#179)

ACP second: rust-lang/libs-team#179 (comment)
New tracking issue: rust-lang#110998

For now this is an `enum` as `@kupiakos` [suggested](rust-lang/libs-team#179 (comment)), with the variants under a different feature flag.

There's lots more things that could be added here, and place for further doc updates, but this seems like a plausible starting point PR.

I've gone through and put an `as_ascii` next to every `is_ascii`: on `u8`, `char`, `[u8]`, and `str`.

As a demonstration, made a commit updating some formatting code to use this: scottmcm@ascii-char-in-fmt (I don't want to include that in this PR, though, because that brings in perf questions that don't exist if this is just adding new unstable APIs.)
  • Loading branch information
matthiaskrgr authored May 4, 2023
2 parents 8d66f01 + 8c781b0 commit ea0b650
Show file tree
Hide file tree
Showing 12 changed files with 724 additions and 1 deletion.
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
#![feature(array_into_iter_constructors)]
#![feature(array_methods)]
#![feature(array_windows)]
#![feature(ascii_char)]
#![feature(assert_matches)]
#![feature(async_iterator)]
#![feature(coerce_unsized)]
Expand Down
9 changes: 9 additions & 0 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2526,6 +2526,15 @@ impl<T: fmt::Display + ?Sized> ToString for T {
}
}

#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "ascii_char", issue = "110998")]
impl ToString for core::ascii::Char {
#[inline]
fn to_string(&self) -> String {
self.as_str().to_owned()
}
}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "char_to_string_specialization", since = "1.46.0")]
impl ToString for char {
Expand Down
34 changes: 34 additions & 0 deletions library/core/src/array/ascii.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use crate::ascii;

#[cfg(not(test))]
impl<const N: usize> [u8; N] {
/// Converts this array of bytes into a array of ASCII characters,
/// or returns `None` if any of the characters is non-ASCII.
#[unstable(feature = "ascii_char", issue = "110998")]
#[must_use]
#[inline]
pub fn as_ascii(&self) -> Option<&[ascii::Char; N]> {
if self.is_ascii() {
// SAFETY: Just checked that it's ASCII
Some(unsafe { self.as_ascii_unchecked() })
} else {
None
}
}

/// Converts this array of bytes into a array of ASCII characters,
/// without checking whether they're valid.
///
/// # Safety
///
/// Every byte in the array must be in `0..=127`, or else this is UB.
#[unstable(feature = "ascii_char", issue = "110998")]
#[must_use]
#[inline]
pub const unsafe fn as_ascii_unchecked(&self) -> &[ascii::Char; N] {
let byte_ptr: *const [u8; N] = self;
let ascii_ptr = byte_ptr as *const [ascii::Char; N];
// SAFETY: The caller promised all the bytes are ASCII
unsafe { &*ascii_ptr }
}
}
1 change: 1 addition & 0 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::ops::{
};
use crate::slice::{Iter, IterMut};

mod ascii;
mod drain;
mod equality;
mod iter;
Expand Down
4 changes: 4 additions & 0 deletions library/core/src/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ use crate::fmt;
use crate::iter::FusedIterator;
use crate::num::NonZeroUsize;

mod ascii_char;
#[unstable(feature = "ascii_char", issue = "110998")]
pub use ascii_char::AsciiChar as Char;

/// An iterator over the escaped version of a byte.
///
/// This `struct` is created by the [`escape_default`] function. See its
Expand Down
Loading

0 comments on commit ea0b650

Please sign in to comment.