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 { }