2020-09-04 13:37:15 +00:00
|
|
|
//! Error types for conversion to integral types.
|
|
|
|
|
|
|
|
|
|
use crate::convert::Infallible;
|
2022-07-29 18:54:47 +00:00
|
|
|
use crate::error::Error;
|
2020-09-04 13:37:15 +00:00
|
|
|
use crate::fmt;
|
|
|
|
|
|
|
|
|
|
/// The error type returned when a checked integral type conversion fails.
|
|
|
|
|
#[stable(feature = "try_from", since = "1.34.0")]
|
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
|
|
|
pub struct TryFromIntError(pub(crate) ());
|
|
|
|
|
|
2023-01-10 15:59:47 +01:00
|
|
|
#[stable(feature = "try_from", since = "1.34.0")]
|
|
|
|
|
impl fmt::Display for TryFromIntError {
|
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
#[allow(deprecated)]
|
|
|
|
|
self.description().fmt(fmt)
|
2020-09-04 13:37:15 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "try_from", since = "1.34.0")]
|
2023-01-10 15:59:47 +01:00
|
|
|
impl Error for TryFromIntError {
|
|
|
|
|
#[allow(deprecated)]
|
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
|
"out of range integral type conversion attempted"
|
2020-09-04 13:37:15 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "try_from", since = "1.34.0")]
|
2023-04-16 06:49:27 +00:00
|
|
|
impl From<Infallible> for TryFromIntError {
|
2020-09-04 13:37:15 +00:00
|
|
|
fn from(x: Infallible) -> TryFromIntError {
|
|
|
|
|
match x {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "never_type", issue = "35121")]
|
2023-04-16 06:49:27 +00:00
|
|
|
impl From<!> for TryFromIntError {
|
2023-04-06 23:42:38 +01:00
|
|
|
#[inline]
|
2020-09-04 13:37:15 +00:00
|
|
|
fn from(never: !) -> TryFromIntError {
|
|
|
|
|
// Match rather than coerce to make sure that code like
|
|
|
|
|
// `From<Infallible> for TryFromIntError` above will keep working
|
|
|
|
|
// when `Infallible` becomes an alias to `!`.
|
|
|
|
|
match never {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An error which can be returned when parsing an integer.
|
|
|
|
|
///
|
|
|
|
|
/// This error is used as the error type for the `from_str_radix()` functions
|
|
|
|
|
/// on the primitive integer types, such as [`i8::from_str_radix`].
|
|
|
|
|
///
|
|
|
|
|
/// # Potential causes
|
|
|
|
|
///
|
|
|
|
|
/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
|
|
|
|
|
/// in the string e.g., when it is obtained from the standard input.
|
2020-12-30 20:38:58 -05:00
|
|
|
/// Using the [`str::trim()`] method ensures that no whitespace remains before parsing.
|
2020-09-04 13:37:15 +00:00
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// if let Err(e) = i32::from_str_radix("a12", 10) {
|
2022-02-12 23:16:17 +04:00
|
|
|
/// println!("Failed conversion to i32: {e}");
|
2020-09-04 13:37:15 +00:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub struct ParseIntError {
|
|
|
|
|
pub(super) kind: IntErrorKind,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Enum to store the various types of errors that can cause parsing an integer to fail.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// # fn main() {
|
|
|
|
|
/// if let Err(e) = i32::from_str_radix("a12", 10) {
|
|
|
|
|
/// println!("Failed conversion to i32: {:?}", e.kind());
|
|
|
|
|
/// }
|
|
|
|
|
/// # }
|
|
|
|
|
/// ```
|
2021-06-22 10:20:56 +01:00
|
|
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
2020-09-04 13:37:15 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
#[non_exhaustive]
|
|
|
|
|
pub enum IntErrorKind {
|
|
|
|
|
/// Value being parsed is empty.
|
|
|
|
|
///
|
2021-05-18 10:37:28 +01:00
|
|
|
/// This variant will be constructed when parsing an empty string.
|
2021-06-22 10:20:56 +01:00
|
|
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
2020-09-04 13:37:15 +00:00
|
|
|
Empty,
|
2020-10-26 05:51:07 -05:00
|
|
|
/// Contains an invalid digit in its context.
|
2020-09-04 13:37:15 +00:00
|
|
|
///
|
|
|
|
|
/// Among other causes, this variant will be constructed when parsing a string that
|
2020-10-26 05:51:22 -05:00
|
|
|
/// contains a non-ASCII char.
|
2020-10-06 22:42:33 +01:00
|
|
|
///
|
2020-10-26 05:50:28 -05:00
|
|
|
/// This variant is also constructed when a `+` or `-` is misplaced within a string
|
2020-10-06 22:42:33 +01:00
|
|
|
/// either on its own or in the middle of a number.
|
2021-06-22 10:20:56 +01:00
|
|
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
2020-10-26 18:14:12 +00:00
|
|
|
InvalidDigit,
|
2020-09-04 13:37:15 +00:00
|
|
|
/// Integer is too large to store in target integer type.
|
2021-06-22 10:20:56 +01:00
|
|
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
2020-10-06 14:06:25 +01:00
|
|
|
PosOverflow,
|
2020-09-04 13:37:15 +00:00
|
|
|
/// Integer is too small to store in target integer type.
|
2021-06-22 10:20:56 +01:00
|
|
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
2020-10-06 14:06:25 +01:00
|
|
|
NegOverflow,
|
2020-09-04 13:37:15 +00:00
|
|
|
/// Value was Zero
|
|
|
|
|
///
|
|
|
|
|
/// This variant will be emitted when the parsing string has a value of zero, which
|
|
|
|
|
/// would be illegal for non-zero types.
|
2021-06-22 10:20:56 +01:00
|
|
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
2020-09-04 13:37:15 +00:00
|
|
|
Zero,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ParseIntError {
|
|
|
|
|
/// Outputs the detailed cause of parsing an integer failing.
|
2021-10-14 18:54:55 -04:00
|
|
|
#[must_use]
|
2021-06-22 10:20:56 +01:00
|
|
|
#[stable(feature = "int_error_matching", since = "1.55.0")]
|
2020-09-04 13:37:15 +00:00
|
|
|
pub fn kind(&self) -> &IntErrorKind {
|
|
|
|
|
&self.kind
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl fmt::Display for ParseIntError {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2023-01-10 15:59:47 +01:00
|
|
|
#[allow(deprecated)]
|
|
|
|
|
self.description().fmt(f)
|
2020-09-04 13:37:15 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-07-29 18:54:47 +00:00
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl Error for ParseIntError {
|
|
|
|
|
#[allow(deprecated)]
|
|
|
|
|
fn description(&self) -> &str {
|
2023-01-10 15:59:47 +01:00
|
|
|
match self.kind {
|
|
|
|
|
IntErrorKind::Empty => "cannot parse integer from empty string",
|
|
|
|
|
IntErrorKind::InvalidDigit => "invalid digit found in string",
|
|
|
|
|
IntErrorKind::PosOverflow => "number too large to fit in target type",
|
|
|
|
|
IntErrorKind::NegOverflow => "number too small to fit in target type",
|
|
|
|
|
IntErrorKind::Zero => "number would be zero for non-zero type",
|
|
|
|
|
}
|
2022-07-29 18:54:47 +00:00
|
|
|
}
|
|
|
|
|
}
|