feat: Add NonZero::<T>::from_str_radix
This commit is contained in:
parent
a3ceeeb26c
commit
d0aa337146
3 changed files with 102 additions and 4 deletions
|
|
@ -1240,16 +1240,78 @@ macro_rules! nonzero_integer {
|
|||
// So the result cannot be zero.
|
||||
unsafe { Self::new_unchecked(self.get().saturating_pow(other)) }
|
||||
}
|
||||
|
||||
/// Parses a non-zero integer from a string slice with digits in a given base.
|
||||
///
|
||||
/// The string is 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
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(nonzero_from_str_radix)]
|
||||
///
|
||||
/// # use std::num::NonZero;
|
||||
/// #
|
||||
/// # fn main() { test().unwrap(); }
|
||||
/// # fn test() -> Option<()> {
|
||||
#[doc = concat!("assert_eq!(NonZero::<", stringify!($Int), ">::from_str_radix(\"A\", 16), Ok(NonZero::new(10)?));")]
|
||||
/// # Some(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Trailing space returns error:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(nonzero_from_str_radix)]
|
||||
///
|
||||
/// # use std::num::NonZero;
|
||||
/// #
|
||||
#[doc = concat!("assert!(NonZero::<", stringify!($Int), ">::from_str_radix(\"1 \", 10).is_err());")]
|
||||
/// ```
|
||||
#[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 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "nonzero_parse", since = "1.35.0")]
|
||||
impl FromStr for NonZero<$Int> {
|
||||
type Err = ParseIntError;
|
||||
fn from_str(src: &str) -> Result<Self, Self::Err> {
|
||||
Self::new(<$Int>::from_str_radix(src, 10)?)
|
||||
.ok_or(ParseIntError {
|
||||
kind: IntErrorKind::Zero
|
||||
})
|
||||
Self::from_str_radix(src, 10)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@
|
|||
#![feature(new_range_api)]
|
||||
#![feature(next_index)]
|
||||
#![feature(non_exhaustive_omitted_patterns_lint)]
|
||||
#![feature(nonzero_from_str_radix)]
|
||||
#![feature(numfmt)]
|
||||
#![feature(one_sided_range)]
|
||||
#![feature(option_reduce)]
|
||||
|
|
|
|||
|
|
@ -124,6 +124,41 @@ fn test_from_signed_nonzero() {
|
|||
assert_eq!(num, 1i32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str_radix() {
|
||||
assert_eq!(NonZero::<u8>::from_str_radix("123", 10), Ok(NonZero::new(123).unwrap()));
|
||||
assert_eq!(NonZero::<u8>::from_str_radix("1001", 2), Ok(NonZero::new(9).unwrap()));
|
||||
assert_eq!(NonZero::<u8>::from_str_radix("123", 8), Ok(NonZero::new(83).unwrap()));
|
||||
assert_eq!(NonZero::<u16>::from_str_radix("123", 16), Ok(NonZero::new(291).unwrap()));
|
||||
assert_eq!(NonZero::<u16>::from_str_radix("ffff", 16), Ok(NonZero::new(65535).unwrap()));
|
||||
assert_eq!(NonZero::<u8>::from_str_radix("z", 36), Ok(NonZero::new(35).unwrap()));
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_str_radix("0", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::Zero)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_str_radix("-1", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::InvalidDigit)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<i8>::from_str_radix("-129", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::NegOverflow)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_str_radix("257", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::PosOverflow)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_str_radix("Z", 10).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::InvalidDigit)
|
||||
);
|
||||
assert_eq!(
|
||||
NonZero::<u8>::from_str_radix("_", 2).err().map(|e| e.kind().clone()),
|
||||
Some(IntErrorKind::InvalidDigit)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!("123".parse::<NonZero<u8>>(), Ok(NonZero::new(123).unwrap()));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue