replace_err/lib.rs
1//! _Sometimes you want to throw errors away._
2//!
3//! This crate does exactly one thing, it adds a new method to the `Result`
4//! type that throws away the current error, if there is one, and replaces
5//! it with a new value. You can see it in action here:
6//!
7//! ```
8//! use replace_err::ReplaceErr as _;
9//!
10//! let result = Err(1);
11//! let result: Result<(), _> = result.replace_err("hello");
12//! assert_eq!(result.unwrap_err(), "hello");
13//! ```
14//!
15//! This is exactly equivalent to calling `Result::map_err` with a closure
16//! which ignores the input and returns something else. In fact, that's how
17//! `replace_err` is implemented.
18//!
19//! Most of the time, you _do not_ want to do this. Usually you want to
20//! wrap prior errors with new layers to add context, giving you a chain
21//! of increasingly-specific and low-level explanations which error
22//! reporters can present to the user, or based on which higher-level code
23//! can take action.
24//!
25//! However, there _are_ some cases where you really don't need the
26//! underlying error, and `replace_err` provides a convenient way to
27//! express that need.
28
29/// Extend `Result` with a `replace_err` method.
30pub trait ReplaceErr: private::Sealed {
31 /// The type of the `Ok` variant in the `Result`.
32 type Ok;
33
34 /// Replace the existing error variant with a new value.
35 fn replace_err<F>(self, err: F) -> Result<Self::Ok, F>;
36}
37
38impl<T, E> ReplaceErr for Result<T, E> {
39 type Ok = T;
40
41 fn replace_err<F>(self, err: F) -> Result<<Self as ReplaceErr>::Ok, F> {
42 self.map_err(|_| err)
43 }
44}
45
46mod private {
47 pub trait Sealed {}
48
49 impl<T, E> Sealed for Result<T, E> {}
50}
51
52#[cfg(test)]
53mod tests {
54 use super::ReplaceErr as _;
55
56 #[test]
57 fn it_works() {
58 // Result<_, i32>
59 let result = Err(1);
60
61 // Result<(), &'static str>
62 // have to specify the Ok variant here, usually it will be clear from context.
63 let result: Result<(), _> = result.replace_err("hello");
64
65 assert_eq!(result.unwrap_err(), "hello");
66 }
67}