]> git.lizzy.rs Git - rust.git/blob - library/core/src/num/error.rs
Rollup merge of #102706 - ferrocene:pa-ignore-doc-index, r=jyn514
[rust.git] / library / core / src / num / error.rs
1 //! Error types for conversion to integral types.
2
3 use crate::convert::Infallible;
4 use crate::error::Error;
5 use 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)]
10 pub struct TryFromIntError(pub(crate) ());
11
12 impl TryFromIntError {
13     #[unstable(
14         feature = "int_error_internals",
15         reason = "available through Error trait and this method should \
16                   not be exposed publicly",
17         issue = "none"
18     )]
19     #[doc(hidden)]
20     pub fn __description(&self) -> &str {
21         "out of range integral type conversion attempted"
22     }
23 }
24
25 #[stable(feature = "try_from", since = "1.34.0")]
26 impl fmt::Display for TryFromIntError {
27     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
28         self.__description().fmt(fmt)
29     }
30 }
31
32 #[stable(feature = "try_from", since = "1.34.0")]
33 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
34 impl const From<Infallible> for TryFromIntError {
35     fn from(x: Infallible) -> TryFromIntError {
36         match x {}
37     }
38 }
39
40 #[unstable(feature = "never_type", issue = "35121")]
41 impl const From<!> for TryFromIntError {
42     fn from(never: !) -> TryFromIntError {
43         // Match rather than coerce to make sure that code like
44         // `From<Infallible> for TryFromIntError` above will keep working
45         // when `Infallible` becomes an alias to `!`.
46         match never {}
47     }
48 }
49
50 /// An error which can be returned when parsing an integer.
51 ///
52 /// This error is used as the error type for the `from_str_radix()` functions
53 /// on the primitive integer types, such as [`i8::from_str_radix`].
54 ///
55 /// # Potential causes
56 ///
57 /// Among other causes, `ParseIntError` can be thrown because of leading or trailing whitespace
58 /// in the string e.g., when it is obtained from the standard input.
59 /// Using the [`str::trim()`] method ensures that no whitespace remains before parsing.
60 ///
61 /// # Example
62 ///
63 /// ```
64 /// if let Err(e) = i32::from_str_radix("a12", 10) {
65 ///     println!("Failed conversion to i32: {e}");
66 /// }
67 /// ```
68 #[derive(Debug, Clone, PartialEq, Eq)]
69 #[stable(feature = "rust1", since = "1.0.0")]
70 pub struct ParseIntError {
71     pub(super) kind: IntErrorKind,
72 }
73
74 /// Enum to store the various types of errors that can cause parsing an integer to fail.
75 ///
76 /// # Example
77 ///
78 /// ```
79 /// # fn main() {
80 /// if let Err(e) = i32::from_str_radix("a12", 10) {
81 ///     println!("Failed conversion to i32: {:?}", e.kind());
82 /// }
83 /// # }
84 /// ```
85 #[stable(feature = "int_error_matching", since = "1.55.0")]
86 #[derive(Debug, Clone, PartialEq, Eq)]
87 #[non_exhaustive]
88 pub enum IntErrorKind {
89     /// Value being parsed is empty.
90     ///
91     /// This variant will be constructed when parsing an empty string.
92     #[stable(feature = "int_error_matching", since = "1.55.0")]
93     Empty,
94     /// Contains an invalid digit in its context.
95     ///
96     /// Among other causes, this variant will be constructed when parsing a string that
97     /// contains a non-ASCII char.
98     ///
99     /// This variant is also constructed when a `+` or `-` is misplaced within a string
100     /// either on its own or in the middle of a number.
101     #[stable(feature = "int_error_matching", since = "1.55.0")]
102     InvalidDigit,
103     /// Integer is too large to store in target integer type.
104     #[stable(feature = "int_error_matching", since = "1.55.0")]
105     PosOverflow,
106     /// Integer is too small to store in target integer type.
107     #[stable(feature = "int_error_matching", since = "1.55.0")]
108     NegOverflow,
109     /// Value was Zero
110     ///
111     /// This variant will be emitted when the parsing string has a value of zero, which
112     /// would be illegal for non-zero types.
113     #[stable(feature = "int_error_matching", since = "1.55.0")]
114     Zero,
115 }
116
117 impl ParseIntError {
118     /// Outputs the detailed cause of parsing an integer failing.
119     #[must_use]
120     #[stable(feature = "int_error_matching", since = "1.55.0")]
121     pub fn kind(&self) -> &IntErrorKind {
122         &self.kind
123     }
124     #[unstable(
125         feature = "int_error_internals",
126         reason = "available through Error trait and this method should \
127                   not be exposed publicly",
128         issue = "none"
129     )]
130     #[doc(hidden)]
131     pub fn __description(&self) -> &str {
132         match self.kind {
133             IntErrorKind::Empty => "cannot parse integer from empty string",
134             IntErrorKind::InvalidDigit => "invalid digit found in string",
135             IntErrorKind::PosOverflow => "number too large to fit in target type",
136             IntErrorKind::NegOverflow => "number too small to fit in target type",
137             IntErrorKind::Zero => "number would be zero for non-zero type",
138         }
139     }
140 }
141
142 #[stable(feature = "rust1", since = "1.0.0")]
143 impl fmt::Display for ParseIntError {
144     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145         self.__description().fmt(f)
146     }
147 }
148
149 #[stable(feature = "rust1", since = "1.0.0")]
150 impl Error for ParseIntError {
151     #[allow(deprecated)]
152     fn description(&self) -> &str {
153         self.__description()
154     }
155 }
156
157 #[stable(feature = "try_from", since = "1.34.0")]
158 impl Error for TryFromIntError {
159     #[allow(deprecated)]
160     fn description(&self) -> &str {
161         self.__description()
162     }
163 }