core/num/
error.rs

1//! Error types for conversion to integral types.
2
3use crate::convert::Infallible;
4use crate::error::Error;
5use crate::fmt;
6
7/// The error type returned when a checked integral type conversion fails.
8#[stable(feature = "try_from", since = "1.34.0")]
9#[derive(Debug, Copy, Clone, PartialEq, Eq)]
10pub struct TryFromIntError(pub(crate) ());
11
12#[stable(feature = "try_from", since = "1.34.0")]
13impl fmt::Display for TryFromIntError {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        "out of range integral type conversion attempted".fmt(f)
16    }
17}
18
19#[stable(feature = "try_from", since = "1.34.0")]
20impl Error for TryFromIntError {}
21
22#[stable(feature = "try_from", since = "1.34.0")]
23#[rustc_const_unstable(feature = "const_try", issue = "74935")]
24impl const From<Infallible> for TryFromIntError {
25    fn from(x: Infallible) -> TryFromIntError {
26        match x {}
27    }
28}
29
30#[unstable(feature = "never_type", issue = "35121")]
31#[rustc_const_unstable(feature = "const_try", issue = "74935")]
32impl const From<!> for TryFromIntError {
33    #[inline]
34    fn from(never: !) -> TryFromIntError {
35        // Match rather than coerce to make sure that code like
36        // `From<Infallible> for TryFromIntError` above will keep working
37        // when `Infallible` becomes an alias to `!`.
38        match never {}
39    }
40}
41
42/// An error which can be returned when parsing an integer.
43///
44/// For example, this error is returned by the `from_str_radix()` functions
45/// on the primitive integer types (such as [`i8::from_str_radix`])
46/// and is used as the error type in their [`FromStr`] implementations.
47///
48/// [`FromStr`]: crate::str::FromStr
49///
50/// # Potential causes
51///
52/// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
53/// in the string e.g., when it is obtained from the standard input.
54/// Using the [`str::trim()`] method ensures that no whitespace remains before parsing.
55///
56/// # Example
57///
58/// ```
59/// if let Err(e) = i32::from_str_radix("a12", 10) {
60///     println!("Failed conversion to i32: {e}");
61/// }
62/// ```
63#[derive(Debug, Clone, PartialEq, Eq)]
64#[stable(feature = "rust1", since = "1.0.0")]
65pub struct ParseIntError {
66    pub(super) kind: IntErrorKind,
67}
68
69/// Enum to store the various types of errors that can cause parsing an integer to fail.
70///
71/// # Example
72///
73/// ```
74/// # fn main() {
75/// if let Err(e) = i32::from_str_radix("a12", 10) {
76///     println!("Failed conversion to i32: {:?}", e.kind());
77/// }
78/// # }
79/// ```
80#[stable(feature = "int_error_matching", since = "1.55.0")]
81#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
82#[non_exhaustive]
83pub enum IntErrorKind {
84    /// Value being parsed is empty.
85    ///
86    /// This variant will be constructed when parsing an empty string.
87    #[stable(feature = "int_error_matching", since = "1.55.0")]
88    Empty,
89    /// Contains an invalid digit in its context.
90    ///
91    /// Among other causes, this variant will be constructed when parsing a string that
92    /// contains a non-ASCII char.
93    ///
94    /// This variant is also constructed when a `+` or `-` is misplaced within a string
95    /// either on its own or in the middle of a number.
96    #[stable(feature = "int_error_matching", since = "1.55.0")]
97    InvalidDigit,
98    /// Integer is too large to store in target integer type.
99    #[stable(feature = "int_error_matching", since = "1.55.0")]
100    PosOverflow,
101    /// Integer is too small to store in target integer type.
102    #[stable(feature = "int_error_matching", since = "1.55.0")]
103    NegOverflow,
104    /// Value was Zero
105    ///
106    /// This variant will be emitted when the parsing string has a value of zero, which
107    /// would be illegal for non-zero types.
108    #[stable(feature = "int_error_matching", since = "1.55.0")]
109    Zero,
110}
111
112impl ParseIntError {
113    /// Outputs the detailed cause of parsing an integer failing.
114    #[must_use]
115    #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
116    #[stable(feature = "int_error_matching", since = "1.55.0")]
117    pub const fn kind(&self) -> &IntErrorKind {
118        &self.kind
119    }
120}
121
122#[stable(feature = "rust1", since = "1.0.0")]
123impl fmt::Display for ParseIntError {
124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125        match self.kind {
126            IntErrorKind::Empty => "cannot parse integer from empty string",
127            IntErrorKind::InvalidDigit => "invalid digit found in string",
128            IntErrorKind::PosOverflow => "number too large to fit in target type",
129            IntErrorKind::NegOverflow => "number too small to fit in target type",
130            IntErrorKind::Zero => "number would be zero for non-zero type",
131        }
132        .fmt(f)
133    }
134}
135
136#[stable(feature = "rust1", since = "1.0.0")]
137impl Error for ParseIntError {}