]>
Commit | Line | Data |
---|---|---|
2c00a5a8 XL |
1 | # `Box`ing errors |
2 | ||
3 | A way to write simple code while preserving the original errors is to [`Box`][box] | |
4 | them. The drawback is that the underlying error type is only known at runtime and not | |
5 | [statically determined][dynamic_dispatch]. | |
6 | ||
7 | The stdlib helps in boxing our errors by having `Box` implement conversion from | |
8 | any type that implements the `Error` trait into the trait object `Box<Error>`, | |
9 | via [`From`][from]. | |
10 | ||
11 | ```rust,editable | |
12 | use std::error; | |
13 | use std::fmt; | |
2c00a5a8 XL |
14 | |
15 | // Change the alias to `Box<error::Error>`. | |
dfeec247 | 16 | type Result<T> = std::result::Result<T, Box<dyn error::Error>>; |
2c00a5a8 XL |
17 | |
18 | #[derive(Debug, Clone)] | |
19 | struct EmptyVec; | |
20 | ||
21 | impl fmt::Display for EmptyVec { | |
22 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
23 | write!(f, "invalid first item to double") | |
24 | } | |
25 | } | |
26 | ||
ba9703b0 | 27 | impl error::Error for EmptyVec {} |
2c00a5a8 XL |
28 | |
29 | fn double_first(vec: Vec<&str>) -> Result<i32> { | |
30 | vec.first() | |
532ac7d7 XL |
31 | .ok_or_else(|| EmptyVec.into()) // Converts to Box |
32 | .and_then(|s| { | |
33 | s.parse::<i32>() | |
34 | .map_err(|e| e.into()) // Converts to Box | |
35 | .map(|i| 2 * i) | |
36 | }) | |
2c00a5a8 XL |
37 | } |
38 | ||
39 | fn print(result: Result<i32>) { | |
40 | match result { | |
532ac7d7 | 41 | Ok(n) => println!("The first doubled is {}", n), |
2c00a5a8 XL |
42 | Err(e) => println!("Error: {}", e), |
43 | } | |
44 | } | |
45 | ||
46 | fn main() { | |
47 | let numbers = vec!["42", "93", "18"]; | |
48 | let empty = vec![]; | |
49 | let strings = vec!["tofu", "93", "18"]; | |
50 | ||
51 | print(double_first(numbers)); | |
52 | print(double_first(empty)); | |
53 | print(double_first(strings)); | |
54 | } | |
55 | ``` | |
56 | ||
57 | ### See also: | |
58 | ||
59 | [Dynamic dispatch][dynamic_dispatch] and [`Error` trait][error] | |
60 | ||
61 | [box]: https://doc.rust-lang.org/std/boxed/struct.Box.html | |
532ac7d7 | 62 | [dynamic_dispatch]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch |
2c00a5a8 XL |
63 | [error]: https://doc.rust-lang.org/std/error/trait.Error.html |
64 | [from]: https://doc.rust-lang.org/std/convert/trait.From.html |