From 46d4f9900c99a5a46a3bc5a7eb7a2a4c48c93398 Mon Sep 17 00:00:00 2001 From: sam skeoch Date: Sat, 22 Feb 2025 17:22:57 +0000 Subject: [PATCH 1/3] Add as_ascii_unchecked() method to primitive type char --- library/core/src/char/methods.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 85cc315626d4b..b178a635c05de 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1202,6 +1202,20 @@ impl char { } } + /// Converts this char into an [ASCII character](`ascii::Char`), without + /// checking whether it is valid. + /// + /// # Safety + /// + /// This char must be within the ASCII range, or else this is UB. + #[must_use] + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const unsafe fn as_ascii_unchecked(&self) -> ascii::Char { + // SAFETY: the caller promised that this char is ASCII. + unsafe { ascii::Char::from_u8_unchecked(*self as u8) } + } + /// Makes a copy of the value in its ASCII upper case equivalent. /// /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', From 82f93a216b3546b1bd028517c5cce3486e2e208e Mon Sep 17 00:00:00 2001 From: sam skeoch Date: Sat, 22 Feb 2025 17:29:04 +0000 Subject: [PATCH 2/3] Add as_ascii_unchecked() method to primitive type u8 --- library/core/src/num/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 80a38a6013dd0..64f4f10f52bb4 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -482,6 +482,20 @@ impl u8 { ascii::Char::from_u8(*self) } + /// Converts this byte to an [ASCII character](ascii::Char), without + /// checking whether or not it's valid. + /// + /// # Safety + /// + /// This byte must be valid ASCII, or else this is UB. + #[must_use] + #[unstable(feature = "ascii_char", issue = "110998")] + #[inline] + pub const unsafe fn as_ascii_unchecked(&self) -> ascii::Char { + // SAFETY: the caller promised that this byte is ASCII. + unsafe { ascii::Char::from_u8_unchecked(*self) } + } + /// Makes a copy of the value in its ASCII upper case equivalent. /// /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', From d5daab44abc1e8fe467b8b2f9af102522f7159f1 Mon Sep 17 00:00:00 2001 From: sam skeoch Date: Sat, 22 Feb 2025 17:35:16 +0000 Subject: [PATCH 3/3] Add as_ascii_unchecked() method to primitive type str --- library/core/src/str/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 4754d18b06eac..3e532bf8d44d1 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2633,6 +2633,21 @@ impl str { self.as_bytes().as_ascii() } + /// Converts this string slice into a slice of [ASCII characters](ascii::Char), + /// without checking whether they are valid. + /// + /// # Safety + /// + /// Every character in this string must be ASCII, or else this is UB. + #[unstable(feature = "ascii_char", issue = "110998")] + #[must_use] + #[inline] + pub const unsafe fn as_ascii_unchecked(&self) -> &[ascii::Char] { + // SAFETY: the caller promised that every byte of this string slice + // is ASCII. + unsafe { self.as_bytes().as_ascii_unchecked() } + } + /// Checks that two strings are an ASCII case-insensitive match. /// /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,