ref_map/result.rs
1/*
2 * result.rs
3 *
4 * ref-map - Convenience methods for references of Option and Result.
5 * Copyright (c) 2020-2021 Ammon Smith
6 *
7 * ref-map is available free of charge under the terms of the MIT
8 * License. You are free to redistribute and/or modify it under those
9 * terms. It is distributed in the hopes that it will be useful, but
10 * WITHOUT ANY WARRANTY. See the LICENSE file for more details.
11 *
12 */
13
14/// Adds the `ref_map()` and `ref_map_err()` extension methods onto [`Result`].
15///
16/// The `ref_map()` method borrows the internal object and passes it
17/// to a closure to be mapped in some way. This allows convenient use
18/// of `as_*` type methods or calculations which require the borrowed
19/// internal value.
20///
21/// ```
22/// # #[derive(Debug, PartialEq, Eq)]
23/// # struct Error;
24/// use ref_map::*;
25///
26/// let answer: Result<Vec<i8>, Error> = Ok(vec![4, 7, 9, 5, 6]);
27///
28/// let filtered = answer.ref_map(|v| &v[3..]);
29/// let answer = &[5, 6];
30///
31/// assert_eq!(filtered, Ok(&answer[..]));
32/// ```
33///
34/// The `ref_map_err()` provides the same, but on the `Err(_)` variant
35/// instead of `Ok(_)`.
36///
37/// ```
38/// # use ref_map::*;
39///
40/// let answer: Result<(), String> = Err("file not found".into());
41///
42/// let error = answer.ref_map_err(|s| s.as_str());
43///
44/// assert_eq!(error, Err("file not found"));
45/// ```
46///
47/// See the crate-level documentation for more information.
48///
49/// [`Result`]: https://doc.rust-lang.org/std/option/enum.Result.html
50pub trait ResultRefMap<'r, T: 'r, E: 'r> {
51 /// Borrows the value in the `Ok` variant and maps it using the provided closure.
52 fn ref_map<U, F>(&'r self, f: F) -> Result<U, &E>
53 where
54 F: FnOnce(&'r T) -> U + 'r;
55
56 /// Borrows the value in the `Err` variant and maps it using the provided closure.
57 fn ref_map_err<D, F>(&'r self, f: F) -> Result<&T, D>
58 where
59 F: FnOnce(&'r E) -> D + 'r;
60}
61
62impl<'r, T: 'r, E: 'r> ResultRefMap<'r, T, E> for Result<T, E> {
63 #[inline]
64 fn ref_map<U, F>(&'r self, f: F) -> Result<U, &E>
65 where
66 F: FnOnce(&'r T) -> U + 'r,
67 {
68 match *self {
69 Ok(ref x) => Ok(f(x)),
70 Err(ref x) => Err(x),
71 }
72 }
73
74 #[inline]
75 fn ref_map_err<D, F>(&'r self, f: F) -> Result<&T, D>
76 where
77 F: FnOnce(&'r E) -> D + 'r,
78 {
79 match *self {
80 Ok(ref x) => Ok(x),
81 Err(ref x) => Err(f(x)),
82 }
83 }
84}