Skip to content

Commit 82678c5

Browse files
committedAug 18, 2016
Implement TryFrom<u32> for char
For symmetry with From<char> for u32.
1 parent 2d8d2a1 commit 82678c5

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed
 

‎src/libcore/char.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use prelude::v1::*;
1919

2020
use char_private::is_printable;
21+
use convert::TryFrom;
2122
use mem::transmute;
2223

2324
// UTF-8 ranges and tags for encoding characters
@@ -123,12 +124,7 @@ pub const MAX: char = '\u{10ffff}';
123124
#[inline]
124125
#[stable(feature = "rust1", since = "1.0.0")]
125126
pub fn from_u32(i: u32) -> Option<char> {
126-
// catch out-of-bounds and surrogates
127-
if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
128-
None
129-
} else {
130-
Some(unsafe { from_u32_unchecked(i) })
131-
}
127+
char::try_from(i).ok()
132128
}
133129

134130
/// Converts a `u32` to a `char`, ignoring validity.
@@ -192,6 +188,25 @@ impl From<u8> for char {
192188
}
193189
}
194190

191+
#[unstable(feature = "try_from", issue = "33417")]
192+
impl TryFrom<u32> for char {
193+
type Err = CharTryFromError;
194+
195+
#[inline]
196+
fn try_from(i: u32) -> Result<Self, Self::Err> {
197+
if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
198+
Err(CharTryFromError(()))
199+
} else {
200+
Ok(unsafe { from_u32_unchecked(i) })
201+
}
202+
}
203+
}
204+
205+
/// The error type returned when a conversion from u32 to char fails.
206+
#[unstable(feature = "try_from", issue = "33417")]
207+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
208+
pub struct CharTryFromError(());
209+
195210
/// Converts a digit in the given radix to a `char`.
196211
///
197212
/// A 'radix' here is sometimes also called a 'base'. A radix of two

‎src/libcoretest/char.rs

+10
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,23 @@
99
// except according to those terms.
1010

1111
use std::char;
12+
use std::convert::TryFrom;
1213

1314
#[test]
1415
fn test_convert() {
1516
assert_eq!(u32::from('a'), 0x61);
1617
assert_eq!(char::from(b'\0'), '\0');
1718
assert_eq!(char::from(b'a'), 'a');
1819
assert_eq!(char::from(b'\xFF'), '\u{FF}');
20+
assert_eq!(char::try_from(0_u32), Ok('\0'));
21+
assert_eq!(char::try_from(0x61_u32), Ok('a'));
22+
assert_eq!(char::try_from(0xD7FF_u32), Ok('\u{D7FF}'));
23+
assert!(char::try_from(0xD800_u32).is_err());
24+
assert!(char::try_from(0xDFFF_u32).is_err());
25+
assert_eq!(char::try_from(0xE000_u32), Ok('\u{E000}'));
26+
assert_eq!(char::try_from(0x10FFFF_u32), Ok('\u{10FFFF}'));
27+
assert!(char::try_from(0x110000_u32).is_err());
28+
assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
1929
}
2030

2131
#[test]

‎src/librustc_unicode/char.rs

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked};
3939
pub use core::char::{EncodeUtf16, EncodeUtf8, EscapeDebug, EscapeDefault, EscapeUnicode};
4040

4141
// unstable reexports
42+
#[unstable(feature = "try_from", issue = "33417")]
43+
pub use core::char::CharTryFromError;
4244
#[unstable(feature = "decode_utf8", issue = "33906")]
4345
pub use core::char::{DecodeUtf8, decode_utf8};
4446
#[unstable(feature = "unicode", issue = "27783")]

‎src/librustc_unicode/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#![feature(decode_utf8)]
3838
#![feature(lang_items)]
3939
#![feature(staged_api)]
40+
#![feature(try_from)]
4041
#![feature(unicode)]
4142

4243
mod tables;

0 commit comments

Comments
 (0)