result_either/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3use core::{
4    ops::{Deref, DerefMut},
5    option::IntoIter,
6};
7
8#[doc(hidden)]
9pub trait ResultLike: Sized {
10    type T;
11    type E;
12
13    fn by(self) -> Result<Self::T, Self::E>;
14
15    fn by_ref(&self) -> Result<&Self::T, &Self::E>;
16
17    fn by_mut(&mut self) -> Result<&mut Self::T, &mut Self::E>;
18}
19
20#[doc(hidden)]
21pub trait ThisRef<'a>: 'a {
22    type Out: ?Sized;
23
24    /// Consume self into reference
25    fn this_ref(self) -> &'a Self::Out;
26}
27
28impl<'a, T: ?Sized> ThisRef<'a> for &'a T {
29    type Out = T;
30
31    fn this_ref(self) -> &'a Self::Out {
32        self
33    }
34}
35impl<'a, T: ?Sized> ThisRef<'a> for &'a mut T {
36    type Out = T;
37
38    fn this_ref(self) -> &'a Self::Out {
39        self
40    }
41}
42
43impl<T, E> ResultLike for Result<T, E> {
44    type T = T;
45    type E = E;
46
47    #[inline]
48    fn by(self) -> Result<Self::T, Self::E> {
49        self
50    }
51
52    #[inline]
53    fn by_ref(&self) -> Result<&Self::T, &Self::E> {
54        self.as_ref()
55    }
56
57    #[inline]
58    fn by_mut(&mut self) -> Result<&mut Self::T, &mut Self::E> {
59        self.as_mut()
60    }
61}
62
63/// [`Result`] extension methods for [`Err`]
64#[allow(private_bounds, private_interfaces)]
65pub trait ResultExt: ResultLike {
66    /// Like [`Result::as_deref`], but on [`Err`]
67    ///
68    /// # Examples
69    /// ```
70    /// # use result_either::ResultExt;
71    /// let x: Result<(), String> = Err("foo".to_owned());
72    /// let y: Result<&(), &str> = x.err_as_deref();
73    /// ```
74    fn err_as_deref(&self) -> Result<&Self::T, &<Self::E as Deref>::Target>
75    where Self::E: Deref,
76    {
77        self.by_ref().map_err(Deref::deref)
78    }
79
80    /// Like [`Result::as_deref_mut`], but on [`Err`]
81    ///
82    /// # Examples
83    /// ```
84    /// # use result_either::ResultExt;
85    /// let mut x: Result<(), String> = Err("foo".to_owned());
86    /// let y: Result<&mut (), &mut str> = x.err_as_deref_mut();
87    /// ```
88    fn err_as_deref_mut(&mut self) -> Result<&mut Self::T, &mut <Self::E as Deref>::Target>
89    where Self::E: DerefMut,
90    {
91        self.by_mut().map_err(DerefMut::deref_mut)
92    }
93
94    /// Like [`Result::copied`], but on [`Err`]
95    ///
96    /// # Examples
97    /// ```
98    /// # use result_either::ResultExt;
99    /// let x: Result<(), &i32> = Err(&2);
100    /// let _: Result<(), i32> = x.copied_err();
101    /// ```
102    fn copied_err<'a>(self) -> Result<Self::T, <Self::E as ThisRef<'a>>::Out>
103    where Self::E: ThisRef<'a>,
104          <Self::E as ThisRef<'a>>::Out: Copy,
105    {
106        self.by().map_err(|e| *e.this_ref())
107    }
108
109    /// Like [`Result::cloned`], but on [`Err`]
110    ///
111    /// # Examples
112    /// ```
113    /// # use result_either::ResultExt;
114    /// let msg = "foo".to_owned();
115    /// let x: Result<(), &String> = Err(&msg);
116    /// let _: Result<(), String> = x.cloned_err();
117    /// ```
118    fn cloned_err<'a>(self) -> Result<Self::T, <Self::E as ThisRef<'a>>::Out>
119    where Self::E: ThisRef<'a>,
120          <Self::E as ThisRef<'a>>::Out: Clone,
121    {
122        self.by().map_err(|e| e.this_ref().clone())
123    }
124
125    /// Like [`Result::iter`], but on [`Err`]
126    ///
127    /// # Examples
128    /// ```
129    /// # use result_either::ResultExt;
130    /// let ok: Result<i32, i32> = Ok(1);
131    /// let err: Result<i32, i32> = Err(1);
132    ///
133    /// assert_eq!(ok.iter_err().next(),  None);
134    /// assert_eq!(err.iter_err().next(), Some(&1));
135    /// ```
136    fn iter_err(&self) -> IntoIter<&Self::E> {
137        self.by_ref().err().into_iter()
138    }
139
140    /// Like [`Result::iter_mut`], but on [`Err`]
141    ///
142    /// # Examples
143    /// ```
144    /// # use result_either::ResultExt;
145    /// let mut ok: Result<i32, i32> = Ok(1);
146    /// let mut err: Result<i32, i32> = Err(1);
147    ///
148    /// assert_eq!(ok.iter_err_mut().next(),  None);
149    /// assert_eq!(err.iter_err_mut().next(), Some(&mut 1));
150    /// ```
151    fn iter_err_mut(&mut self) -> IntoIter<&mut Self::E> {
152        self.by_mut().err().into_iter()
153    }
154
155    /// Like [`Result::into_iter`], but on [`Err`]
156    ///
157    /// # Examples
158    /// ```
159    /// # use result_either::ResultExt;
160    /// let ok: Result<i32, i32> = Ok(1);
161    /// let err: Result<i32, i32> = Err(1);
162    ///
163    /// assert_eq!(ok.into_iter_err().next(),  None);
164    /// assert_eq!(err.into_iter_err().next(), Some(1));
165    /// ```
166    fn into_iter_err(self) -> IntoIter<Self::E> {
167        self.by().err().into_iter()
168    }
169
170    /// Like [`Result::map_or`], but on [`Err`]
171    ///
172    /// # Examples
173    /// ```
174    /// # use result_either::ResultExt;
175    /// let ok: Result<i32, &str> = Ok(1);
176    /// let err: Result<i32, &str> = Err("err");
177    ///
178    /// assert_eq!(ok.map_err_or(0, str::len),  0);
179    /// assert_eq!(err.map_err_or(0, str::len), 3);
180    /// ```
181    fn map_err_or<E, F>(self, default: E, f: F) -> E
182    where F: FnOnce(Self::E) -> E,
183    {
184        match self.by() {
185            Ok(_) => default,
186            Err(e) => f(e),
187        }
188    }
189
190    /// Like [`Result::map_or_else`], but on [`Err`]
191    ///
192    /// # Examples
193    /// ```
194    /// # use result_either::ResultExt;
195    /// let ok: Result<usize, &str> = Ok(1);
196    /// let err: Result<usize, &str> = Err("err");
197    ///
198    /// assert_eq!(ok.map_err_or_else(|n| n*2, str::len),  2);
199    /// assert_eq!(err.map_err_or_else(|n| n*2, str::len), 3);
200    /// ```
201    fn map_err_or_else<E, D, F>(self, default: D, f: F) -> E
202    where F: FnOnce(Self::E) -> E,
203          D: FnOnce(Self::T) -> E,
204    {
205        match self.by() {
206            Ok(ok) => default(ok),
207            Err(e) => f(e),
208        }
209    }
210
211    /// Like [`Result::unwrap_or`], but on [`Err`]
212    ///
213    /// # Examples
214    /// ```
215    /// # use result_either::ResultExt;
216    /// let ok: Result<usize, &str> = Ok(1);
217    /// let err: Result<usize, &str> = Err("err");
218    ///
219    /// assert_eq!(ok.unwrap_err_or("ok"),  "ok");
220    /// assert_eq!(err.unwrap_err_or("ok"), "err");
221    /// ```
222    fn unwrap_err_or(self, default: Self::E) -> Self::E {
223        match self.by() {
224            Ok(_) => default,
225            Err(e) => e,
226        }
227    }
228
229    /// Like [`Result::unwrap_or_else`], but on [`Err`]
230    ///
231    /// # Examples
232    /// ```
233    /// # use result_either::ResultExt;
234    /// let ok: Result<usize, &str> = Ok(1);
235    /// let err: Result<usize, &str> = Err("err");
236    ///
237    /// assert_eq!(ok.unwrap_err_or_else(|_| "ok"),  "ok");
238    /// assert_eq!(err.unwrap_err_or_else(|_| "ok"), "err");
239    /// ```
240    fn unwrap_err_or_else<F>(self, op: F) -> Self::E
241    where F: FnOnce(Self::T) -> Self::E,
242    {
243        match self.by() {
244            Ok(ok) => op(ok),
245            Err(e) => e,
246        }
247    }
248
249    /// Like [`Result::unwrap_or_default`], but on [`Err`]
250    ///
251    /// # Examples
252    /// ```
253    /// # use result_either::ResultExt;
254    /// let ok: Result<usize, &str> = Ok(1);
255    /// let err: Result<usize, &str> = Err("err");
256    ///
257    /// assert_eq!(ok.unwrap_err_or_default(),  "");
258    /// assert_eq!(err.unwrap_err_or_default(), "err");
259    /// ```
260    fn unwrap_err_or_default(self) -> Self::E
261    where Self::E: Default,
262    {
263        match self.by() {
264            Ok(_) => Default::default(),
265            Err(e) => e,
266        }
267    }
268
269    /// Like [`Result::transpose`], but on [`Err`]
270    ///
271    /// # Examples
272    /// ```
273    /// # use result_either::ResultExt;
274    /// let ok: Result<i32, Option<i32>> = Ok(1);
275    /// let none: Result<i32, Option<i32>> = Err(None);
276    /// let some: Result<i32, Option<i32>> = Err(Some(3));
277    ///
278    /// assert_eq!(ok.transpose_err(),   Some(Ok(1)));
279    /// assert_eq!(none.transpose_err(), None);
280    /// assert_eq!(some.transpose_err(), Some(Err(3)));
281    /// ```
282    fn transpose_err<E>(self) -> Option<Result<Self::T, E>>
283    where Self: ResultLike<E = Option<E>>,
284    {
285        match self.by() {
286            Ok(x) => Some(Ok(x)),
287            Err(Some(e)) => Some(Err(e)),
288            Err(None) => None,
289        }
290    }
291
292    /// Like `self.map_err(Into::into)`
293    ///
294    /// # Examples
295    /// ```
296    /// # use result_either::ResultExt;
297    /// let e: Result<(), &str> = Err("foo");
298    /// let e1: Result<(), String> = e.err_into();
299    /// assert_eq!(e1, Err("foo".to_owned()));
300    /// ```
301    fn err_into<E>(self) -> Result<Self::T, E>
302    where Self::E: Into<E>,
303    {
304        self.by().map_err(Into::into)
305    }
306
307    /// Map `Ok(x) => Err(x)`, `Err(x) => Ok(x)`
308    ///
309    /// # Examples
310    ///
311    /// ```
312    /// # use result_either::ResultExt;
313    /// let ok:  Result<i32, i32> = Ok(3);
314    /// let err: Result<i32, i32> = Err(4);
315    /// assert_eq!(ok.flip(), Err(3));
316    /// assert_eq!(err.flip(), Ok(4));
317    /// ```
318    fn flip(self) -> Result<Self::E, Self::T> {
319        match self.by() {
320            Ok(x) => Err(x),
321            Err(x) => Ok(x),
322        }
323    }
324
325    /// Unpack `Result<T, T>`
326    ///
327    /// # Examples
328    ///
329    /// ```
330    /// # use result_either::ResultExt;
331    /// let ok:  Result<i32, i32> = Ok(3);
332    /// let err: Result<i32, i32> = Err(4);
333    /// assert_eq!(ok.into_inner(), 3);
334    /// assert_eq!(err.into_inner(), 4);
335    /// ```
336    fn into_inner<O>(self) -> O
337    where Self: ResultExt<T = O, E = O>,
338    {
339        match self.by() {
340            Ok(x) | Err(x) => x,
341        }
342    }
343}
344impl<T: ResultLike> ResultExt for T { }