]>
Commit | Line | Data |
---|---|---|
f2b60f7d FG |
1 | ### What it does |
2 | Checks for instances of `map_err(|_| Some::Enum)` | |
3 | ||
4 | ### Why is this bad? | |
5 | This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error | |
6 | ||
7 | ### Example | |
8 | Before: | |
9 | ``` | |
10 | use std::fmt; | |
11 | ||
12 | #[derive(Debug)] | |
13 | enum Error { | |
14 | Indivisible, | |
15 | Remainder(u8), | |
16 | } | |
17 | ||
18 | impl fmt::Display for Error { | |
19 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
20 | match self { | |
21 | Error::Indivisible => write!(f, "could not divide input by three"), | |
22 | Error::Remainder(remainder) => write!( | |
23 | f, | |
24 | "input is not divisible by three, remainder = {}", | |
25 | remainder | |
26 | ), | |
27 | } | |
28 | } | |
29 | } | |
30 | ||
31 | impl std::error::Error for Error {} | |
32 | ||
33 | fn divisible_by_3(input: &str) -> Result<(), Error> { | |
34 | input | |
35 | .parse::<i32>() | |
36 | .map_err(|_| Error::Indivisible) | |
37 | .map(|v| v % 3) | |
38 | .and_then(|remainder| { | |
39 | if remainder == 0 { | |
40 | Ok(()) | |
41 | } else { | |
42 | Err(Error::Remainder(remainder as u8)) | |
43 | } | |
44 | }) | |
45 | } | |
46 | ``` | |
47 | ||
48 | After: | |
49 | ```rust | |
50 | use std::{fmt, num::ParseIntError}; | |
51 | ||
52 | #[derive(Debug)] | |
53 | enum Error { | |
54 | Indivisible(ParseIntError), | |
55 | Remainder(u8), | |
56 | } | |
57 | ||
58 | impl fmt::Display for Error { | |
59 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
60 | match self { | |
61 | Error::Indivisible(_) => write!(f, "could not divide input by three"), | |
62 | Error::Remainder(remainder) => write!( | |
63 | f, | |
64 | "input is not divisible by three, remainder = {}", | |
65 | remainder | |
66 | ), | |
67 | } | |
68 | } | |
69 | } | |
70 | ||
71 | impl std::error::Error for Error { | |
72 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { | |
73 | match self { | |
74 | Error::Indivisible(source) => Some(source), | |
75 | _ => None, | |
76 | } | |
77 | } | |
78 | } | |
79 | ||
80 | fn divisible_by_3(input: &str) -> Result<(), Error> { | |
81 | input | |
82 | .parse::<i32>() | |
83 | .map_err(Error::Indivisible) | |
84 | .map(|v| v % 3) | |
85 | .and_then(|remainder| { | |
86 | if remainder == 0 { | |
87 | Ok(()) | |
88 | } else { | |
89 | Err(Error::Remainder(remainder as u8)) | |
90 | } | |
91 | }) | |
92 | } | |
93 | ``` |