1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
//! Error types for conversion to integral types.
use crate::convert::Infallible;
use crate::error::Error;
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) ());
#[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)
}
}
#[stable(feature = "try_from", since = "1.34.0")]
impl Error for TryFromIntError {
#[allow(deprecated)]
fn description(&self) -> &str {
"out of range integral type conversion attempted"
}
}
#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
fn from(x: Infallible) -> TryFromIntError {
match x {}
}
}
#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
#[inline]
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.
/// Using the [`str::trim()`] method ensures that no whitespace remains before parsing.
///
/// # Example
///
/// ```
/// if let Err(e) = i32::from_str_radix("a12", 10) {
/// println!("Failed conversion to i32: {e}");
/// }
/// ```
#[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());
/// }
/// # }
/// ```
#[stable(feature = "int_error_matching", since = "1.55.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum IntErrorKind {
/// Value being parsed is empty.
///
/// This variant will be constructed when parsing an empty string.
#[stable(feature = "int_error_matching", since = "1.55.0")]
Empty,
/// Contains an invalid digit in its context.
///
/// Among other causes, this variant will be constructed when parsing a string that
/// contains a non-ASCII char.
///
/// This variant is also constructed when a `+` or `-` is misplaced within a string
/// either on its own or in the middle of a number.
#[stable(feature = "int_error_matching", since = "1.55.0")]
InvalidDigit,
/// Integer is too large to store in target integer type.
#[stable(feature = "int_error_matching", since = "1.55.0")]
PosOverflow,
/// Integer is too small to store in target integer type.
#[stable(feature = "int_error_matching", since = "1.55.0")]
NegOverflow,
/// 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.
#[stable(feature = "int_error_matching", since = "1.55.0")]
Zero,
}
impl ParseIntError {
/// Outputs the detailed cause of parsing an integer failing.
#[must_use]
#[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
#[stable(feature = "int_error_matching", since = "1.55.0")]
pub const 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 {
#[allow(deprecated)]
self.description().fmt(f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for ParseIntError {
#[allow(deprecated)]
fn description(&self) -> &str {
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",
}
}
}