Skip to main content

tuwunel_core/utils/result/
flat_ok.rs

1use super::Result;
2
3/// Flattens optional and fallible values while discarding their original error.
4///
5/// Implementations cover both `Option<Result<T, E>>` and
6/// `Result<Option<T>, E>`. Missing values and errors both become absence before
7/// an optional replacement error is applied.
8pub trait FlatOk<T> {
9	/// Equivalent to .transpose().ok().flatten()
10	fn flat_ok(self) -> Option<T>;
11
12	/// Equivalent to .transpose().ok().flatten().ok_or(...)
13	fn flat_ok_or<E>(self, err: E) -> Result<T, E>;
14
15	/// Equivalent to .transpose().ok().flatten().ok_or_else(...)
16	fn flat_ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E>;
17}
18
19impl<T, E> FlatOk<T> for Option<Result<T, E>> {
20	#[inline]
21	fn flat_ok(self) -> Option<T> { self.transpose().ok().flatten() }
22
23	#[inline]
24	fn flat_ok_or<Ep>(self, err: Ep) -> Result<T, Ep> { self.flat_ok().ok_or(err) }
25
26	#[inline]
27	fn flat_ok_or_else<Ep, F: FnOnce() -> Ep>(self, err: F) -> Result<T, Ep> {
28		self.flat_ok().ok_or_else(err)
29	}
30}
31
32impl<T, E> FlatOk<T> for Result<Option<T>, E> {
33	#[inline]
34	fn flat_ok(self) -> Option<T> { self.ok().flatten() }
35
36	#[inline]
37	fn flat_ok_or<Ep>(self, err: Ep) -> Result<T, Ep> { self.flat_ok().ok_or(err) }
38
39	#[inline]
40	fn flat_ok_or_else<Ep, F: FnOnce() -> Ep>(self, err: F) -> Result<T, Ep> {
41		self.flat_ok().ok_or_else(err)
42	}
43}