Implement TryFrom<u32> for char

For symmetry with From<char> for u32.
This commit is contained in:
Simon Sapin 2016-08-17 18:01:41 +02:00
parent 41d0a89e3a
commit f040208d53
5 changed files with 49 additions and 6 deletions

View File

@ -16,6 +16,8 @@
#![stable(feature = "core_char", since = "1.2.0")]
use char_private::is_printable;
use convert::TryFrom;
use fmt;
use iter::FusedIterator;
use mem::transmute;
@ -122,12 +124,7 @@ pub const MAX: char = '\u{10ffff}';
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_u32(i: u32) -> Option<char> {
// catch out-of-bounds and surrogates
if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
None
} else {
Some(unsafe { from_u32_unchecked(i) })
}
char::try_from(i).ok()
}
/// Converts a `u32` to a `char`, ignoring validity.
@ -209,6 +206,32 @@ impl From<u8> for char {
}
}
#[unstable(feature = "try_from", issue = "33417")]
impl TryFrom<u32> for char {
type Err = CharTryFromError;
#[inline]
fn try_from(i: u32) -> Result<Self, Self::Err> {
if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
Err(CharTryFromError(()))
} else {
Ok(unsafe { from_u32_unchecked(i) })
}
}
}
/// The error type returned when a conversion from u32 to char fails.
#[unstable(feature = "try_from", issue = "33417")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CharTryFromError(());
#[unstable(feature = "try_from", issue = "33417")]
impl fmt::Display for CharTryFromError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
"converted integer out of range for `char`".fmt(f)
}
}
/// Converts a digit in the given radix to a `char`.
///
/// A 'radix' here is sometimes also called a 'base'. A radix of two

View File

@ -9,6 +9,7 @@
// except according to those terms.
use std::char;
use std::convert::TryFrom;
#[test]
fn test_convert() {
@ -16,6 +17,15 @@ fn test_convert() {
assert_eq!(char::from(b'\0'), '\0');
assert_eq!(char::from(b'a'), 'a');
assert_eq!(char::from(b'\xFF'), '\u{FF}');
assert_eq!(char::try_from(0_u32), Ok('\0'));
assert_eq!(char::try_from(0x61_u32), Ok('a'));
assert_eq!(char::try_from(0xD7FF_u32), Ok('\u{D7FF}'));
assert!(char::try_from(0xD800_u32).is_err());
assert!(char::try_from(0xDFFF_u32).is_err());
assert_eq!(char::try_from(0xE000_u32), Ok('\u{E000}'));
assert_eq!(char::try_from(0x10FFFF_u32), Ok('\u{10FFFF}'));
assert!(char::try_from(0x110000_u32).is_err());
assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
}
#[test]

View File

@ -40,6 +40,8 @@ pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked};
pub use core::char::{EncodeUtf16, EncodeUtf8, EscapeDebug, EscapeDefault, EscapeUnicode};
// unstable reexports
#[unstable(feature = "try_from", issue = "33417")]
pub use core::char::CharTryFromError;
#[unstable(feature = "decode_utf8", issue = "33906")]
pub use core::char::{DecodeUtf8, decode_utf8};
#[unstable(feature = "unicode", issue = "27783")]

View File

@ -38,6 +38,7 @@
#![feature(fused)]
#![feature(lang_items)]
#![feature(staged_api)]
#![feature(try_from)]
#![feature(unicode)]
mod tables;

View File

@ -302,6 +302,13 @@ impl<'a, T: ?Sized + Reflect> Error for cell::BorrowMutError<'a, T> {
}
}
#[unstable(feature = "try_from", issue = "33417")]
impl Error for char::CharTryFromError {
fn description(&self) -> &str {
"converted integer out of range for `char`"
}
}
// copied from any.rs
impl Error + 'static {
/// Returns true if the boxed type is the same as `T`