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