|
| 1 | +#![allow(missing_docs)] |
| 2 | + |
1 | 3 | use core::fmt::{Debug, Display}; |
2 | 4 |
|
3 | | -/// `Error` is a trait representing the basic expectations for error values, |
4 | | -/// i.e., values of type `E` in `Result<T, E>`. Errors must describe |
5 | | -/// themselves through the `Display` and `Debug` traits, and may provide |
6 | | -/// cause chain information: |
7 | | -/// |
8 | | -/// The [`source`] method is generally used when errors cross "abstraction |
9 | | -/// boundaries". If one module must report an error that is caused by an error |
10 | | -/// from a lower-level module, it can allow access to that error via the |
11 | | -/// [`source`] method. This makes it possible for the high-level module to |
12 | | -/// provide its own errors while also revealing some of the implementation for |
13 | | -/// debugging via [`source`] chains. |
14 | | -/// |
15 | | -/// [`source`]: trait.Error.html#method.source |
16 | 5 | pub trait Error: Debug + Display { |
17 | | - /// **This method is soft-deprecated.** |
18 | | - /// |
19 | | - /// Although using it won’t cause compilation warning, |
20 | | - /// new code should use `Display` instead |
21 | | - /// and new `impl`s can omit it. |
22 | | - /// |
23 | | - /// To obtain error description as a string, use `to_string()`. |
24 | | - /// |
25 | | - /// # Examples |
26 | | - /// |
27 | | - /// ``` |
28 | | - /// match "xc".parse::<u32>() { |
29 | | - /// Err(e) => { |
30 | | - /// // Print `e` itself, not `e.description()`. |
31 | | - /// println!("Error: {}", e); |
32 | | - /// } |
33 | | - /// _ => println!("No error"), |
34 | | - /// } |
35 | | - /// ``` |
36 | 6 | fn description(&self) -> &str { |
37 | 7 | "description() is deprecated; use Display" |
38 | 8 | } |
39 | | - |
40 | | - /// The lower-level cause of this error, if any. |
41 | | - /// |
42 | | - /// # Examples |
43 | | - /// |
44 | | - /// ``` |
45 | | - /// use snafu::Error; |
46 | | - /// use core::fmt; |
47 | | - /// |
48 | | - /// #[derive(Debug)] |
49 | | - /// struct SuperError { |
50 | | - /// side: SuperErrorSideKick, |
51 | | - /// } |
52 | | - /// |
53 | | - /// impl fmt::Display for SuperError { |
54 | | - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
55 | | - /// write!(f, "SuperError is here!") |
56 | | - /// } |
57 | | - /// } |
58 | | - /// |
59 | | - /// impl Error for SuperError { |
60 | | - /// fn description(&self) -> &str { |
61 | | - /// "I'm the superhero of errors" |
62 | | - /// } |
63 | | - /// |
64 | | - /// fn cause(&self) -> Option<&dyn Error> { |
65 | | - /// Some(&self.side) |
66 | | - /// } |
67 | | - /// } |
68 | | - /// |
69 | | - /// #[derive(Debug)] |
70 | | - /// struct SuperErrorSideKick; |
71 | | - /// |
72 | | - /// impl fmt::Display for SuperErrorSideKick { |
73 | | - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
74 | | - /// write!(f, "SuperErrorSideKick is here!") |
75 | | - /// } |
76 | | - /// } |
77 | | - /// |
78 | | - /// impl Error for SuperErrorSideKick { |
79 | | - /// fn description(&self) -> &str { |
80 | | - /// "I'm SuperError side kick" |
81 | | - /// } |
82 | | - /// } |
83 | | - /// |
84 | | - /// fn get_super_error() -> Result<(), SuperError> { |
85 | | - /// Err(SuperError { side: SuperErrorSideKick }) |
86 | | - /// } |
87 | | - /// |
88 | | - /// fn main() { |
89 | | - /// match get_super_error() { |
90 | | - /// Err(e) => { |
91 | | - /// println!("Error: {}", e.description()); |
92 | | - /// println!("Caused by: {}", e.cause().unwrap()); |
93 | | - /// } |
94 | | - /// _ => println!("No error"), |
95 | | - /// } |
96 | | - /// } |
97 | | - /// ``` |
98 | | - fn cause(&self) -> Option<&dyn Error> { |
| 9 | + fn cause(&self) -> Option<&Error> { |
99 | 10 | self.source() |
100 | 11 | } |
101 | | - |
102 | | - /// The lower-level source of this error, if any. |
103 | | - /// |
104 | | - /// # Examples |
105 | | - /// |
106 | | - /// ``` |
107 | | - /// use snafu::Error; |
108 | | - /// use core::fmt; |
109 | | - /// |
110 | | - /// #[derive(Debug)] |
111 | | - /// struct SuperError { |
112 | | - /// side: SuperErrorSideKick, |
113 | | - /// } |
114 | | - /// |
115 | | - /// impl fmt::Display for SuperError { |
116 | | - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
117 | | - /// write!(f, "SuperError is here!") |
118 | | - /// } |
119 | | - /// } |
120 | | - /// |
121 | | - /// impl Error for SuperError { |
122 | | - /// fn description(&self) -> &str { |
123 | | - /// "I'm the superhero of errors" |
124 | | - /// } |
125 | | - /// |
126 | | - /// fn source(&self) -> Option<&(dyn Error + 'static)> { |
127 | | - /// Some(&self.side) |
128 | | - /// } |
129 | | - /// } |
130 | | - /// |
131 | | - /// #[derive(Debug)] |
132 | | - /// struct SuperErrorSideKick; |
133 | | - /// |
134 | | - /// impl fmt::Display for SuperErrorSideKick { |
135 | | - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
136 | | - /// write!(f, "SuperErrorSideKick is here!") |
137 | | - /// } |
138 | | - /// } |
139 | | - /// |
140 | | - /// impl Error for SuperErrorSideKick { |
141 | | - /// fn description(&self) -> &str { |
142 | | - /// "I'm SuperError side kick" |
143 | | - /// } |
144 | | - /// } |
145 | | - /// |
146 | | - /// fn get_super_error() -> Result<(), SuperError> { |
147 | | - /// Err(SuperError { side: SuperErrorSideKick }) |
148 | | - /// } |
149 | | - /// |
150 | | - /// fn main() { |
151 | | - /// match get_super_error() { |
152 | | - /// Err(e) => { |
153 | | - /// println!("Error: {}", e.description()); |
154 | | - /// println!("Caused by: {}", e.source().unwrap()); |
155 | | - /// } |
156 | | - /// _ => println!("No error"), |
157 | | - /// } |
158 | | - /// } |
159 | | - /// ``` |
160 | | - fn source(&self) -> Option<&(dyn Error + 'static)> { |
| 12 | + fn source(&self) -> Option<&(Error + 'static)> { |
161 | 13 | None |
162 | 14 | } |
163 | 15 | } |
164 | 16 |
|
165 | | -impl Error for core::str::ParseBoolError { |
166 | | - fn description(&self) -> &str { |
167 | | - "failed to parse bool" |
168 | | - } |
169 | | -} |
170 | | -impl Error for core::str::Utf8Error { |
171 | | - fn description(&self) -> &str { |
172 | | - "invalid utf-8: corrupt contents" |
173 | | - } |
174 | | -} |
175 | | -impl Error for core::num::ParseIntError {} |
176 | | -impl Error for core::num::TryFromIntError {} |
177 | | -impl Error for core::array::TryFromSliceError {} |
178 | | -impl Error for core::num::ParseFloatError {} |
179 | | -impl Error for core::fmt::Error { |
180 | | - fn description(&self) -> &str { |
181 | | - "an error occurred when formatting an argument" |
182 | | - } |
183 | | -} |
184 | | -impl Error for core::cell::BorrowError { |
185 | | - fn description(&self) -> &str { |
186 | | - "already mutably borrowed" |
187 | | - } |
188 | | -} |
189 | | -impl Error for core::cell::BorrowMutError { |
190 | | - fn description(&self) -> &str { |
191 | | - "already borrowed" |
| 17 | +macro_rules! impl_error { |
| 18 | + ($($e:path),*) => { |
| 19 | + $( |
| 20 | + impl Error for $e {} |
| 21 | + )* |
192 | 22 | } |
193 | 23 | } |
194 | | -impl Error for core::char::CharTryFromError { |
195 | | - fn description(&self) -> &str { |
196 | | - "converted integer out of range for `char`" |
197 | | - } |
198 | | -} |
199 | | -impl Error for core::char::ParseCharError {} |
| 24 | + |
| 25 | +// All errors supported by our minimum suported Rust version can be supported by |
| 26 | +// default. |
| 27 | +impl_error![ |
| 28 | + core::str::ParseBoolError, // 1.0 |
| 29 | + core::str::Utf8Error, // 1.0 |
| 30 | + core::num::ParseIntError, // 1.0 |
| 31 | + core::num::ParseFloatError, // 1.0 |
| 32 | + core::char::DecodeUtf16Error, // 1.9 |
| 33 | + core::fmt::Error, // 1.11 |
| 34 | + core::cell::BorrowMutError, // 1.13 |
| 35 | + core::cell::BorrowError // 1.13 |
| 36 | +]; |
| 37 | + |
| 38 | +#[cfg(feature = "rust_1_30")] |
| 39 | +impl_error![core::char::ParseCharError]; // 1.20 |
| 40 | + |
| 41 | +// We can gate these together with std futures. |
| 42 | +#[cfg(feature = "unstable-futures")] |
| 43 | +impl_error![ |
| 44 | + core::num::TryFromIntError, // 1.34 |
| 45 | + core::array::TryFromSliceError, // 1.34 |
| 46 | + core::char::CharTryFromError // 1.34 |
| 47 | +]; |
0 commit comments