Skip to main content

tuwunel_core/utils/future/
option_ext.rs

1#![expect(clippy::wrong_self_convention)]
2
3use futures::{Future, FutureExt, future::OptionFuture};
4
5use super::super::BoolExt;
6
7pub trait OptionFutureExt<T> {
8	fn is_none_or(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future<Output = bool> + Send;
9
10	fn is_some_and(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future<Output = bool> + Send;
11
12	fn unwrap_or(self, t: T) -> impl Future<Output = T> + Send;
13
14	fn unwrap_or_default(self) -> impl Future<Output = T> + Send
15	where
16		T: Default;
17
18	fn unwrap_or_else(self, f: impl FnOnce() -> T + Send) -> impl Future<Output = T> + Send;
19
20	fn unwrap_or_else_async<F: Future<Output = T> + Send>(
21		self,
22		f: impl FnOnce() -> F + Send,
23	) -> impl Future<Output = Option<T>> + Send;
24}
25
26impl<T, Fut> OptionFutureExt<T> for OptionFuture<Fut>
27where
28	Fut: Future<Output = T> + Send,
29	T: Send,
30{
31	#[inline]
32	fn is_none_or(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future<Output = bool> + Send {
33		self.map(|o| o.as_ref().is_none_or(f))
34	}
35
36	#[inline]
37	fn is_some_and(self, f: impl FnOnce(&T) -> bool + Send) -> impl Future<Output = bool> + Send {
38		self.map(|o| o.as_ref().is_some_and(f))
39	}
40
41	#[inline]
42	fn unwrap_or(self, t: T) -> impl Future<Output = T> + Send { self.map(|o| o.unwrap_or(t)) }
43
44	#[inline]
45	fn unwrap_or_default(self) -> impl Future<Output = T> + Send
46	where
47		T: Default,
48	{
49		self.map(Option::unwrap_or_default)
50	}
51
52	#[inline]
53	fn unwrap_or_else(self, f: impl FnOnce() -> T + Send) -> impl Future<Output = T> + Send {
54		self.map(|o| o.unwrap_or_else(f))
55	}
56
57	#[inline]
58	fn unwrap_or_else_async<F: Future<Output = T> + Send>(
59		self,
60		f: impl FnOnce() -> F + Send,
61	) -> impl Future<Output = Option<T>> + Send {
62		self.map(|o| o.is_none().then_async(f)).flatten()
63	}
64}