From a02639dc09fa0cde2cec73e6260d6702e165b8ce Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Tue, 27 Apr 2021 21:05:26 -0700 Subject: [PATCH] Implement `TryFrom` for `u8` Previously suggested in https://github.com/rust-lang/rfcs/issues/2854. It makes sense to have this since `char` implements `From`. Likewise `u32`, `u64`, and `u128` (since #79502) implement `From`. --- library/core/src/char/convert.rs | 15 +++++++++++++++ library/core/src/char/mod.rs | 12 ++++++++++++ library/std/src/error.rs | 3 +++ 3 files changed, 30 insertions(+) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index c4046d7496f71..1774ddd7cbb2c 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -1,5 +1,6 @@ //! Character conversions. +use crate::char::TryFromCharError; use crate::convert::TryFrom; use crate::fmt; use crate::mem::transmute; @@ -166,6 +167,20 @@ impl const From for u128 { } } +/// Map `char` with code point in U+0000..=U+00FF to byte in 0x00..=0xFF with same value, failing +/// if the code point is greater than U+00FF. +/// +/// See [`impl From for char`](char#impl-From) for details on the encoding. +#[stable(feature = "u8_from_char", since = "1.59.0")] +impl TryFrom for u8 { + type Error = TryFromCharError; + + #[inline] + fn try_from(c: char) -> Result { + u8::try_from(u32::from(c)).map_err(|_| TryFromCharError(())) + } +} + /// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF. /// /// Unicode is designed such that this effectively decodes bytes diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 5f30d5790a04f..f65f84e93aebe 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -544,3 +544,15 @@ impl fmt::Display for ToUppercase { fmt::Display::fmt(&self.0, f) } } + +/// The error type returned when a checked char conversion fails. +#[stable(feature = "u8_from_char", since = "1.59.0")] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct TryFromCharError(pub(crate) ()); + +#[stable(feature = "u8_from_char", since = "1.59.0")] +impl fmt::Display for TryFromCharError { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + "unicode code point out of range".fmt(fmt) + } +} diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 6ae0bc47a9462..ea0c230fa42db 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -478,6 +478,9 @@ impl Error for char::DecodeUtf16Error { } } +#[stable(feature = "u8_from_char", since = "1.59.0")] +impl Error for char::TryFromCharError {} + #[unstable(feature = "map_try_insert", issue = "82766")] impl<'a, K: Debug + Ord, V: Debug> Error for crate::collections::btree_map::OccupiedError<'a, K, V>