      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
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154

    //! Error types for conversion to integral types.

    use crate::convert::Infallible;
    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) ());

    impl TryFromIntError {
        #[unstable(
            feature = "int_error_internals",
            reason = "available through Error trait and this method should \
                      not be exposed publicly",
            issue = "none"
        )]
        #[doc(hidden)]
        pub fn __description(&self) -> &str {
            "out of range integral type conversion attempted"
        }
    }

    #[stable(feature = "try_from", since = "1.34.0")]
    impl fmt::Display for TryFromIntError {
        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
            self.__description().fmt(fmt)
        }
    }

    #[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 {
        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.
    ///
    /// [`str.trim()`]: ../../std/primitive.str.html#method.trim
    /// [`i8::from_str_radix`]: ../../std/primitive.i8.html#method.from_str_radix
    ///
    /// # 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
    ///
    /// ```
    /// #![feature(int_error_matching)]
    ///
    /// # fn main() {
    /// if let Err(e) = i32::from_str_radix("a12", 10) {
    ///     println!("Failed conversion to i32: {:?}", e.kind());
    /// }
    /// # }
    /// ```
    #[unstable(
        feature = "int_error_matching",
        reason = "it can be useful to match errors when making error messages \
                  for integer parsing",
        issue = "22639"
    )]
    #[derive(Debug, Clone, PartialEq, Eq)]
    #[non_exhaustive]
    pub enum IntErrorKind {
        /// Value being parsed is empty.
        ///
        /// Among other causes, this variant will be constructed when parsing an empty string.
        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.
        InvalidDigit,
        /// Integer is too large to store in target integer type.
        PosOverflow,
        /// Integer is too small to store in target integer type.
        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.
        Zero,
    }

    impl ParseIntError {
        /// Outputs the detailed cause of parsing an integer failing.
        #[unstable(
            feature = "int_error_matching",
            reason = "it can be useful to match errors when making error messages \
                  for integer parsing",
            issue = "22639"
        )]
        pub fn kind(&self) -> &IntErrorKind {
            &self.kind
        }
        #[unstable(
            feature = "int_error_internals",
            reason = "available through Error trait and this method should \
                      not be exposed publicly",
            issue = "none"
        )]
        #[doc(hidden)]
        pub 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",
            }
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl fmt::Display for ParseIntError {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            self.__description().fmt(f)
        }
    }