tuwunel_core/utils/future/
try_ext_ext.rs1#![expect(clippy::type_complexity)]
3#![expect(clippy::wrong_self_convention)]
6
7use std::marker::Unpin;
8
9use futures::{
10 TryFuture, TryFutureExt, future,
11 future::{MapOkOrElse, TrySelect, UnwrapOrElse},
12};
13
14pub trait TryExtExt<T, E>
16where
17 Self: TryFuture<Ok = T, Error = E> + Send,
18{
19 fn is_err(
20 self,
21 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
22 where
23 Self: Sized;
24
25 #[expect(clippy::wrong_self_convention)]
26 fn is_ok(
27 self,
28 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
29 where
30 Self: Sized;
31
32 fn map_ok_or<U, F>(
33 self,
34 default: U,
35 f: F,
36 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> U, impl FnOnce(Self::Error) -> U>
37 where
38 F: FnOnce(Self::Ok) -> U,
39 Self: Send + Sized;
40
41 fn ok(
42 self,
43 ) -> MapOkOrElse<
44 Self,
45 impl FnOnce(Self::Ok) -> Option<Self::Ok>,
46 impl FnOnce(Self::Error) -> Option<Self::Ok>,
47 >
48 where
49 Self: Sized;
50
51 fn try_until<A, B, F>(self, f: F) -> TrySelect<A, B>
52 where
53 Self: Sized,
54 F: FnOnce() -> B,
55 A: TryFuture<Ok = Self::Ok> + From<Self> + Send + Unpin,
56 B: TryFuture<Ok = (), Error = Self::Error> + Send + Unpin;
57
58 fn unwrap_or(
59 self,
60 default: Self::Ok,
61 ) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
62 where
63 Self: Sized;
64
65 fn unwrap_or_default(self) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
66 where
67 Self: Sized,
68 Self::Ok: Default;
69}
70
71impl<T, E, Fut> TryExtExt<T, E> for Fut
72where
73 Fut: TryFuture<Ok = T, Error = E> + Send,
74{
75 #[inline]
76 fn is_err(
77 self,
78 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
79 where
80 Self: Sized,
81 {
82 self.map_ok_or(true, |_| false)
83 }
84
85 #[inline]
86 fn is_ok(
87 self,
88 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
89 where
90 Self: Sized,
91 {
92 self.map_ok_or(false, |_| true)
93 }
94
95 #[inline]
96 fn map_ok_or<U, F>(
97 self,
98 default: U,
99 f: F,
100 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> U, impl FnOnce(Self::Error) -> U>
101 where
102 F: FnOnce(Self::Ok) -> U,
103 Self: Send + Sized,
104 {
105 self.map_ok_or_else(|_| default, f)
106 }
107
108 #[inline]
109 fn ok(
110 self,
111 ) -> MapOkOrElse<
112 Self,
113 impl FnOnce(Self::Ok) -> Option<Self::Ok>,
114 impl FnOnce(Self::Error) -> Option<Self::Ok>,
115 >
116 where
117 Self: Sized,
118 {
119 self.map_ok_or(None, Some)
120 }
121
122 #[inline]
123 fn try_until<A, B, F>(self, f: F) -> TrySelect<A, B>
124 where
125 Self: Sized,
126 F: FnOnce() -> B,
127 A: TryFuture<Ok = Self::Ok> + From<Self> + Send + Unpin,
128 B: TryFuture<Ok = (), Error = Self::Error> + Send + Unpin,
129 {
130 future::try_select(self.into(), f())
131 }
132
133 #[inline]
134 fn unwrap_or(
135 self,
136 default: Self::Ok,
137 ) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
138 where
139 Self: Sized,
140 {
141 self.unwrap_or_else(move |_| default)
142 }
143
144 #[inline]
145 fn unwrap_or_default(self) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
146 where
147 Self: Sized,
148 Self::Ok: Default,
149 {
150 self.unwrap_or(Default::default())
151 }
152}