tuwunel_core/utils/future/
try_ext_ext.rs1#![expect(clippy::type_complexity)]
3#![expect(clippy::wrong_self_convention)]
6
7use futures::{
8 TryFuture, TryFutureExt, future,
9 future::{MapOkOrElse, TrySelect, UnwrapOrElse},
10};
11
12pub trait TryExtExt<T, E>
18where
19 Self: TryFuture<Ok = T, Error = E> + Send,
20{
21 fn is_err(
26 self,
27 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
28 where
29 Self: Sized;
30
31 #[expect(clippy::wrong_self_convention)]
36 fn is_ok(
37 self,
38 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
39 where
40 Self: Sized;
41
42 fn map_ok_or<U, F>(
47 self,
48 default: U,
49 f: F,
50 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> U, impl FnOnce(Self::Error) -> U>
51 where
52 F: FnOnce(Self::Ok) -> U,
53 Self: Send + Sized;
54
55 fn ok(
60 self,
61 ) -> MapOkOrElse<
62 Self,
63 impl FnOnce(Self::Ok) -> Option<Self::Ok>,
64 impl FnOnce(Self::Error) -> Option<Self::Ok>,
65 >
66 where
67 Self: Sized;
68
69 fn try_until<A, B, F>(self, f: F) -> TrySelect<A, B>
75 where
76 Self: Sized,
77 F: FnOnce() -> B,
78 A: TryFuture<Ok = Self::Ok> + From<Self> + Send + Unpin,
79 B: TryFuture<Ok = (), Error = Self::Error> + Send + Unpin;
80
81 fn unwrap_or(
86 self,
87 default: Self::Ok,
88 ) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
89 where
90 Self: Sized;
91
92 fn unwrap_or_default(self) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
97 where
98 Self: Sized,
99 Self::Ok: Default;
100}
101
102impl<T, E, Fut> TryExtExt<T, E> for Fut
103where
104 Fut: TryFuture<Ok = T, Error = E> + Send,
105{
106 #[inline]
107 fn is_err(
108 self,
109 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
110 where
111 Self: Sized,
112 {
113 self.map_ok_or(true, |_| false)
114 }
115
116 #[inline]
117 fn is_ok(
118 self,
119 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> bool, impl FnOnce(Self::Error) -> bool>
120 where
121 Self: Sized,
122 {
123 self.map_ok_or(false, |_| true)
124 }
125
126 #[inline]
127 fn map_ok_or<U, F>(
128 self,
129 default: U,
130 f: F,
131 ) -> MapOkOrElse<Self, impl FnOnce(Self::Ok) -> U, impl FnOnce(Self::Error) -> U>
132 where
133 F: FnOnce(Self::Ok) -> U,
134 Self: Send + Sized,
135 {
136 self.map_ok_or_else(|_| default, f)
137 }
138
139 #[inline]
140 fn ok(
141 self,
142 ) -> MapOkOrElse<
143 Self,
144 impl FnOnce(Self::Ok) -> Option<Self::Ok>,
145 impl FnOnce(Self::Error) -> Option<Self::Ok>,
146 >
147 where
148 Self: Sized,
149 {
150 self.map_ok_or(None, Some)
151 }
152
153 #[inline]
154 fn try_until<A, B, F>(self, f: F) -> TrySelect<A, B>
155 where
156 Self: Sized,
157 F: FnOnce() -> B,
158 A: TryFuture<Ok = Self::Ok> + From<Self> + Send + Unpin,
159 B: TryFuture<Ok = (), Error = Self::Error> + Send + Unpin,
160 {
161 future::try_select(self.into(), f())
162 }
163
164 #[inline]
165 fn unwrap_or(
166 self,
167 default: Self::Ok,
168 ) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
169 where
170 Self: Sized,
171 {
172 self.unwrap_or_else(move |_| default)
173 }
174
175 #[inline]
176 fn unwrap_or_default(self) -> UnwrapOrElse<Self, impl FnOnce(Self::Error) -> Self::Ok>
177 where
178 Self: Sized,
179 Self::Ok: Default,
180 {
181 self.unwrap_or(Default::default())
182 }
183}