Rollup merge of #42271 - tinaun:charfromstr, r=alexcrichton
add `FromStr` Impl for `char` fixes #24939. is it possible to use pub(restricted) instead of using a stability attribute for the internal error representation? is it needed at all?
This commit is contained in:
@@ -19,7 +19,7 @@ use char_private::is_printable;
|
||||
use convert::TryFrom;
|
||||
use fmt::{self, Write};
|
||||
use slice;
|
||||
use str::from_utf8_unchecked_mut;
|
||||
use str::{from_utf8_unchecked_mut, FromStr};
|
||||
use iter::FusedIterator;
|
||||
use mem::transmute;
|
||||
|
||||
@@ -208,6 +208,63 @@ impl From<u8> for char {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// An error which can be returned when parsing a char.
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ParseCharError {
|
||||
kind: CharErrorKind,
|
||||
}
|
||||
|
||||
impl ParseCharError {
|
||||
#[unstable(feature = "char_error_internals",
|
||||
reason = "this method should not be available publicly",
|
||||
issue = "0")]
|
||||
#[doc(hidden)]
|
||||
pub fn __description(&self) -> &str {
|
||||
match self.kind {
|
||||
CharErrorKind::EmptyString => {
|
||||
"cannot parse char from empty string"
|
||||
},
|
||||
CharErrorKind::TooManyChars => "too many characters in string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum CharErrorKind {
|
||||
EmptyString,
|
||||
TooManyChars,
|
||||
}
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
impl fmt::Display for ParseCharError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.__description().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
impl FromStr for char {
|
||||
type Err = ParseCharError;
|
||||
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut chars = s.chars();
|
||||
match (chars.next(), chars.next()) {
|
||||
(None, _) => {
|
||||
Err(ParseCharError { kind: CharErrorKind::EmptyString })
|
||||
},
|
||||
(Some(c), None) => Ok(c),
|
||||
_ => {
|
||||
Err(ParseCharError { kind: CharErrorKind::TooManyChars })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<u32> for char {
|
||||
type Error = CharTryFromError;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
use std::{char,str};
|
||||
use std::convert::TryFrom;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_convert() {
|
||||
@@ -28,6 +29,16 @@ fn test_convert() {
|
||||
assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(char::from_str("a").unwrap(), 'a');
|
||||
assert_eq!(char::try_from("a").unwrap(), 'a');
|
||||
assert_eq!(char::from_str("\0").unwrap(), '\0');
|
||||
assert_eq!(char::from_str("\u{D7FF}").unwrap(), '\u{d7FF}');
|
||||
assert!(char::from_str("").is_err());
|
||||
assert!(char::from_str("abc").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_lowercase() {
|
||||
assert!('a'.is_lowercase());
|
||||
|
||||
Reference in New Issue
Block a user