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}