Skip to main content

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::as_deref`], but on [`Ok`] and [`Err`]
95    ///
96    /// # Examples
97    /// ```
98    /// # use result_either::ResultExt;
99    /// let x: Result<String, String> = Err("foo".to_owned());
100    /// let y: &str = x.either_as_deref();
101    /// ```
102    fn either_as_deref(&self) -> &<Self::T as Deref>::Target
103    where Self::T: Deref,
104          Self::E: Deref<Target = <Self::T as Deref>::Target>
105    {
106        match self.by_ref() {
107            Ok(x) => x,
108            Err(x) => x,
109        }
110    }
111
112    /// Like [`Result::as_deref`], but on [`Ok`] and [`Err`]
113    ///
114    /// # Examples
115    /// ```
116    /// # use result_either::ResultExt;
117    /// let x: Result<String, String> = Err("foo".to_owned());
118    /// let y: &str = x.either_as_deref();
119    /// ```
120    fn either_as_deref_mut(&mut self) -> &mut <Self::T as Deref>::Target
121    where Self::T: DerefMut,
122          Self::E: DerefMut<Target = <Self::T as Deref>::Target>
123    {
124        match self.by_mut() {
125            Ok(x) => x,
126            Err(x) => x,
127        }
128    }
129
130    /// Like [`Result::copied`], but on [`Err`]
131    ///
132    /// # Examples
133    /// ```
134    /// # use result_either::ResultExt;
135    /// let x: Result<(), &i32> = Err(&2);
136    /// let _: Result<(), i32> = x.copied_err();
137    /// ```
138    fn copied_err<'a>(self) -> Result<Self::T, <Self::E as ThisRef<'a>>::Out>
139    where Self::E: ThisRef<'a>,
140          <Self::E as ThisRef<'a>>::Out: Copy,
141    {
142        self.by().map_err(|e| *e.this_ref())
143    }
144
145    /// Like [`Result::cloned`], but on [`Err`]
146    ///
147    /// # Examples
148    /// ```
149    /// # use result_either::ResultExt;
150    /// let msg = "foo".to_owned();
151    /// let x: Result<(), &String> = Err(&msg);
152    /// let _: Result<(), String> = x.cloned_err();
153    /// ```
154    fn cloned_err<'a>(self) -> Result<Self::T, <Self::E as ThisRef<'a>>::Out>
155    where Self::E: ThisRef<'a>,
156          <Self::E as ThisRef<'a>>::Out: Clone,
157    {
158        self.by().map_err(|e| e.this_ref().clone())
159    }
160
161    /// Like [`Result::iter`], but on [`Err`]
162    ///
163    /// # Examples
164    /// ```
165    /// # use result_either::ResultExt;
166    /// let ok: Result<i32, i32> = Ok(1);
167    /// let err: Result<i32, i32> = Err(1);
168    ///
169    /// assert_eq!(ok.iter_err().next(),  None);
170    /// assert_eq!(err.iter_err().next(), Some(&1));
171    /// ```
172    fn iter_err(&self) -> IntoIter<&Self::E> {
173        self.by_ref().err().into_iter()
174    }
175
176    /// Like [`Result::iter_mut`], but on [`Err`]
177    ///
178    /// # Examples
179    /// ```
180    /// # use result_either::ResultExt;
181    /// let mut ok: Result<i32, i32> = Ok(1);
182    /// let mut err: Result<i32, i32> = Err(1);
183    ///
184    /// assert_eq!(ok.iter_err_mut().next(),  None);
185    /// assert_eq!(err.iter_err_mut().next(), Some(&mut 1));
186    /// ```
187    fn iter_err_mut(&mut self) -> IntoIter<&mut Self::E> {
188        self.by_mut().err().into_iter()
189    }
190
191    /// Like [`Result::into_iter`], but on [`Err`]
192    ///
193    /// # Examples
194    /// ```
195    /// # use result_either::ResultExt;
196    /// let ok: Result<i32, i32> = Ok(1);
197    /// let err: Result<i32, i32> = Err(1);
198    ///
199    /// assert_eq!(ok.into_iter_err().next(),  None);
200    /// assert_eq!(err.into_iter_err().next(), Some(1));
201    /// ```
202    fn into_iter_err(self) -> IntoIter<Self::E> {
203        self.by().err().into_iter()
204    }
205
206    /// Like [`Result::map_or`], but on [`Err`]
207    ///
208    /// # Examples
209    /// ```
210    /// # use result_either::ResultExt;
211    /// let ok: Result<i32, &str> = Ok(1);
212    /// let err: Result<i32, &str> = Err("err");
213    ///
214    /// assert_eq!(ok.map_err_or(0, str::len),  0);
215    /// assert_eq!(err.map_err_or(0, str::len), 3);
216    /// ```
217    fn map_err_or<E, F>(self, default: E, f: F) -> E
218    where F: FnOnce(Self::E) -> E,
219    {
220        match self.by() {
221            Ok(_) => default,
222            Err(e) => f(e),
223        }
224    }
225
226    /// Like [`Result::map_or_else`], but on [`Err`]
227    ///
228    /// # Examples
229    /// ```
230    /// # use result_either::ResultExt;
231    /// let ok: Result<usize, &str> = Ok(1);
232    /// let err: Result<usize, &str> = Err("err");
233    ///
234    /// assert_eq!(ok.map_err_or_else(|n| n*2, str::len),  2);
235    /// assert_eq!(err.map_err_or_else(|n| n*2, str::len), 3);
236    /// ```
237    fn map_err_or_else<E, D, F>(self, default: D, f: F) -> E
238    where F: FnOnce(Self::E) -> E,
239          D: FnOnce(Self::T) -> E,
240    {
241        match self.by() {
242            Ok(ok) => default(ok),
243            Err(e) => f(e),
244        }
245    }
246
247    /// Like [`Result::unwrap_or`], but on [`Err`]
248    ///
249    /// # Examples
250    /// ```
251    /// # use result_either::ResultExt;
252    /// let ok: Result<usize, &str> = Ok(1);
253    /// let err: Result<usize, &str> = Err("err");
254    ///
255    /// assert_eq!(ok.unwrap_err_or("ok"),  "ok");
256    /// assert_eq!(err.unwrap_err_or("ok"), "err");
257    /// ```
258    fn unwrap_err_or(self, default: Self::E) -> Self::E {
259        match self.by() {
260            Ok(_) => default,
261            Err(e) => e,
262        }
263    }
264
265    /// Like [`Result::unwrap_or_else`], but on [`Err`]
266    ///
267    /// # Examples
268    /// ```
269    /// # use result_either::ResultExt;
270    /// let ok: Result<usize, &str> = Ok(1);
271    /// let err: Result<usize, &str> = Err("err");
272    ///
273    /// assert_eq!(ok.unwrap_err_or_else(|_| "ok"),  "ok");
274    /// assert_eq!(err.unwrap_err_or_else(|_| "ok"), "err");
275    /// ```
276    fn unwrap_err_or_else<F>(self, op: F) -> Self::E
277    where F: FnOnce(Self::T) -> Self::E,
278    {
279        match self.by() {
280            Ok(ok) => op(ok),
281            Err(e) => e,
282        }
283    }
284
285    /// Like [`Result::unwrap_or_default`], but on [`Err`]
286    ///
287    /// # Examples
288    /// ```
289    /// # use result_either::ResultExt;
290    /// let ok: Result<usize, &str> = Ok(1);
291    /// let err: Result<usize, &str> = Err("err");
292    ///
293    /// assert_eq!(ok.unwrap_err_or_default(),  "");
294    /// assert_eq!(err.unwrap_err_or_default(), "err");
295    /// ```
296    fn unwrap_err_or_default(self) -> Self::E
297    where Self::E: Default,
298    {
299        match self.by() {
300            Ok(_) => Default::default(),
301            Err(e) => e,
302        }
303    }
304
305    /// Like [`Result::transpose`], but on [`Err`]
306    ///
307    /// # Examples
308    /// ```
309    /// # use result_either::ResultExt;
310    /// let ok: Result<i32, Option<i32>> = Ok(1);
311    /// let none: Result<i32, Option<i32>> = Err(None);
312    /// let some: Result<i32, Option<i32>> = Err(Some(3));
313    ///
314    /// assert_eq!(ok.transpose_err(),   Some(Ok(1)));
315    /// assert_eq!(none.transpose_err(), None);
316    /// assert_eq!(some.transpose_err(), Some(Err(3)));
317    /// ```
318    fn transpose_err<E>(self) -> Option<Result<Self::T, E>>
319    where Self: ResultLike<E = Option<E>>,
320    {
321        match self.by() {
322            Ok(x) => Some(Ok(x)),
323            Err(Some(e)) => Some(Err(e)),
324            Err(None) => None,
325        }
326    }
327
328    /// Like `self.map_err(Into::into)`
329    ///
330    /// # Examples
331    /// ```
332    /// # use result_either::ResultExt;
333    /// let e: Result<(), &str> = Err("foo");
334    /// let e1: Result<(), String> = e.err_into();
335    /// assert_eq!(e1, Err("foo".to_owned()));
336    /// ```
337    fn err_into<E>(self) -> Result<Self::T, E>
338    where Self::E: Into<E>,
339    {
340        self.by().map_err(Into::into)
341    }
342
343    /// Map `Ok(x) => Err(x)`, `Err(x) => Ok(x)`
344    ///
345    /// # Examples
346    ///
347    /// ```
348    /// # use result_either::ResultExt;
349    /// let ok:  Result<i32, i32> = Ok(3);
350    /// let err: Result<i32, i32> = Err(4);
351    /// assert_eq!(ok.flip(), Err(3));
352    /// assert_eq!(err.flip(), Ok(4));
353    /// ```
354    fn flip(self) -> Result<Self::E, Self::T> {
355        match self.by() {
356            Ok(x) => Err(x),
357            Err(x) => Ok(x),
358        }
359    }
360
361    /// Unpack `Result<T, T>`
362    ///
363    /// # Examples
364    ///
365    /// ```
366    /// # use result_either::ResultExt;
367    /// let ok:  Result<i32, i32> = Ok(3);
368    /// let err: Result<i32, i32> = Err(4);
369    /// assert_eq!(ok.into_inner(), 3);
370    /// assert_eq!(err.into_inner(), 4);
371    /// ```
372    fn into_inner<O>(self) -> O
373    where Self: ResultExt<T = O, E = O>,
374    {
375        match self.by() {
376            Ok(x) | Err(x) => x,
377        }
378    }
379}
380impl<T: ResultLike> ResultExt for T { }