feat: Implement int_from_ascii for NonZero<T>
This commit is contained in:
parent
c58d9f9f82
commit
d837cf6700
3 changed files with 166 additions and 11 deletions
|
|
@ -1241,6 +1241,114 @@ macro_rules! nonzero_integer {
|
|||
unsafe { Self::new_unchecked(self.get().saturating_pow(other)) }
|
||||
}
|
||||
|
||||
/// Parses a non-zero integer from an ASCII-byte slice with decimal digits.
|
||||
///
|
||||
/// The characters are expected to be an optional
|
||||
#[doc = sign_dependent_expr!{
|
||||
$signedness ?
|
||||
if signed {
|
||||
" `+` or `-` "
|
||||
}
|
||||
if unsigned {
|
||||
" `+` "
|
||||
}
|
||||
}]
|
||||
/// sign followed by only digits. Leading and trailing non-digit characters (including
|
||||
/// whitespace) represent an error. Underscores (which are accepted in Rust literals)
|
||||
/// also represent an error.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(int_from_ascii)]
|
||||
///
|
||||
/// # use std::num::NonZero;
|
||||
/// #
|
||||
/// # fn main() { test().unwrap(); }
|
||||
/// # fn test() -> Option<()> {
|
||||
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::from_ascii(b\"+10\"), Ok(NonZero::new(10)?));")]
|
||||
/// # Some(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Trailing space returns error:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(int_from_ascii)]
|
||||
///
|
||||
/// # use std::num::NonZero;
|
||||
/// #
|
||||
#[doc = concat!("assert!(NonZero::<", stringify!($Int), ">::from_ascii(b\"1 \").is_err());")]
|
||||
/// ```
|
||||
#[unstable(feature = "int_from_ascii", issue = "134821")]
|
||||
#[inline]
|
||||
pub const fn from_ascii(src: &[u8]) -> Result<Self, ParseIntError> {
|
||||
Self::from_ascii_radix(src, 10)
|
||||
}
|
||||
|
||||
/// Parses a non-zero integer from an ASCII-byte slice with digits in a given base.
|
||||
///
|
||||
/// The characters are expected to be an optional
|
||||
#[doc = sign_dependent_expr!{
|
||||
$signedness ?
|
||||
if signed {
|
||||
" `+` or `-` "
|
||||
}
|
||||
if unsigned {
|
||||
" `+` "
|
||||
}
|
||||
}]
|
||||
/// sign followed by only digits. Leading and trailing non-digit characters (including
|
||||
/// whitespace) represent an error. Underscores (which are accepted in Rust literals)
|
||||
/// also represent an error.
|
||||
///
|
||||
/// Digits are a subset of these characters, depending on `radix`:
|
||||
///
|
||||
/// - `0-9`
|
||||
/// - `a-z`
|
||||
/// - `A-Z`
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This method panics if `radix` is not in the range from 2 to 36.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(int_from_ascii)]
|
||||
///
|
||||
/// # use std::num::NonZero;
|
||||
/// #
|
||||
/// # fn main() { test().unwrap(); }
|
||||
/// # fn test() -> Option<()> {
|
||||
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::from_ascii_radix(b\"A\", 16), Ok(NonZero::new(10)?));")]
|
||||
/// # Some(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Trailing space returns error:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(int_from_ascii)]
|
||||
///
|
||||
/// # use std::num::NonZero;
|
||||
/// #
|
||||
#[doc = concat!("assert!(NonZero::<", stringify!($Int), ">::from_ascii_radix(b\"1 \", 10).is_err());")]
|
||||
/// ```
|
||||
#[unstable(feature = "int_from_ascii", issue = "134821")]
|
||||
#[inline]
|
||||
pub const fn from_ascii_radix(src: &[u8], radix: u32) -> Result<Self, ParseIntError> {
|
||||
let n = match <$Int>::from_ascii_radix(src, radix) {
|
||||
Ok(n) => n,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
if let Some(n) = Self::new(n) {
|
||||
Ok(n)
|
||||
} else {
|
||||
Err(ParseIntError { kind: IntErrorKind::Zero })
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a non-zero integer from a string slice with digits in a given base.
|
||||
///
|
||||
/// The string is expected to be an optional
|
||||
|
|
@ -1269,8 +1377,6 @@ macro_rules! nonzero_integer {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(nonzero_from_str_radix)]
|
||||
///
|
||||
|
|
@ -1295,15 +1401,7 @@ macro_rules! nonzero_integer {
|
|||
#[unstable(feature = "nonzero_from_str_radix", issue = "152193")]
|
||||
#[inline]
|
||||
pub const fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
|
||||
let n = match <$Int>::from_str_radix(src, radix) {
|
||||
Ok(n) => n,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
if let Some(n) = Self::new(n) {
|
||||
Ok(n)
|
||||
} else {
|
||||
Err(ParseIntError { kind: IntErrorKind::Zero })
|
||||
}
|
||||
Self::from_ascii_radix(src.as_bytes(), radix)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
#![feature(generic_assert_internals)]
|
||||
#![feature(hasher_prefixfree_extras)]
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(int_from_ascii)]
|
||||
#![feature(int_lowest_highest_one)]
|
||||
#![feature(int_roundings)]
|
||||
#![feature(ip)]
|
||||
|
|
|
|||
|
|
@ -124,6 +124,62 @@ fn test_from_signed_nonzero() {
|
|||
assert_eq!(num, 1i32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_ascii_radix() {
|
||||
assert_eq!(NonZero::<u8>::from_ascii_radix(b"123", 10), Ok(NonZero::new(123).unwrap()));
|
||||
assert_eq!(NonZero::<u8>::from_ascii_radix(b"1001", 2), Ok(NonZero::new(9).unwrap()));
|
||||
assert_eq!(NonZero::<u8>::from_ascii_radix(b"123", 8), Ok(NonZero::new(83).unwrap()));
|
||||
assert_eq!(NonZero::<u16>::from_ascii_radix(b"123", 16), Ok(NonZero::new(291).unwrap()));
|
||||
assert_eq!(NonZero::<u16>::from_ascii_radix(b"ffff", 16), Ok(NonZero::new(65535).unwrap()));
|
||||
assert_eq!(NonZero::<u8>::from_ascii_radix(b"z", 36), Ok(NonZero::new(35).unwrap()));
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii_radix(b"0", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::Zero)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii_radix(b"-1", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::InvalidDigit)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<i8>::from_ascii_radix(b"-129", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::NegOverflow)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii_radix(b"257", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::PosOverflow)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii_radix(b"Z", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::InvalidDigit)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii_radix(b"_", 2).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::InvalidDigit)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_ascii() {
|
||||
assert_eq!(NonZero::<u8>::from_ascii(b"123"), Ok(NonZero::new(123).unwrap()));
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii(b"0").err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::Zero)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii(b"-1").err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::InvalidDigit)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<i8>::from_ascii(b"-129").err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::NegOverflow)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_ascii(b"257").err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::PosOverflow)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str_radix() {
|
||||
assert_eq!(NonZero::<u8>::from_str_radix("123", 10), Ok(NonZero::new(123).unwrap()));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue