1#![expect(clippy::type_complexity)]
3
4use futures::{
5 future::{FutureExt, Ready, ready},
6 stream::{
7 All, Any, Filter, FilterMap, Fold, ForEach, Scan, SkipWhile, Stream, StreamExt, TakeWhile,
8 },
9};
10
11pub trait ReadyExt<Item>
16where
17 Self: Stream<Item = Item> + Sized,
18{
19 fn ready_all<F>(self, f: F) -> All<Self, Ready<bool>, impl FnMut(Item) -> Ready<bool>>
24 where
25 F: Fn(Item) -> bool;
26
27 fn ready_any<F>(self, f: F) -> Any<Self, Ready<bool>, impl FnMut(Item) -> Ready<bool>>
32 where
33 F: Fn(Item) -> bool;
34
35 fn ready_find<'a, F>(self, f: F) -> impl Future<Output = Option<Item>> + Send
40 where
41 Self: Send + Unpin + 'a,
42 F: Fn(&Item) -> bool + Send + 'a,
43 Item: Send;
44
45 fn ready_find_map<'a, F, U>(self, f: F) -> impl Future<Output = Option<U>> + Send
50 where
51 Self: Send + Unpin + 'a,
52 F: Fn(Item) -> Option<U> + Send + 'a,
53 Item: Send,
54 U: Send;
55
56 fn ready_filter<'a, F>(
61 self,
62 f: F,
63 ) -> Filter<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
64 where
65 F: Fn(&Item) -> bool + 'a;
66
67 fn ready_filter_map<F, U>(
72 self,
73 f: F,
74 ) -> FilterMap<Self, Ready<Option<U>>, impl FnMut(Item) -> Ready<Option<U>>>
75 where
76 F: Fn(Item) -> Option<U>;
77
78 fn ready_fold<T, F>(
83 self,
84 init: T,
85 f: F,
86 ) -> Fold<Self, Ready<T>, T, impl FnMut(T, Item) -> Ready<T>>
87 where
88 F: Fn(T, Item) -> T;
89
90 fn ready_fold_default<T, F>(
95 self,
96 f: F,
97 ) -> Fold<Self, Ready<T>, T, impl FnMut(T, Item) -> Ready<T>>
98 where
99 F: Fn(T, Item) -> T,
100 T: Default;
101
102 fn ready_for_each<F>(self, f: F) -> ForEach<Self, Ready<()>, impl FnMut(Item) -> Ready<()>>
107 where
108 F: FnMut(Item);
109
110 fn ready_take_while<'a, F>(
115 self,
116 f: F,
117 ) -> TakeWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
118 where
119 F: Fn(&Item) -> bool + 'a;
120
121 fn ready_scan<B, T, F>(
126 self,
127 init: T,
128 f: F,
129 ) -> Scan<Self, T, Ready<Option<B>>, impl FnMut(&mut T, Item) -> Ready<Option<B>>>
130 where
131 F: Fn(&mut T, Item) -> Option<B>;
132
133 fn ready_scan_each<T, F>(
138 self,
139 init: T,
140 f: F,
141 ) -> Scan<Self, T, Ready<Option<Item>>, impl FnMut(&mut T, Item) -> Ready<Option<Item>>>
142 where
143 F: Fn(&mut T, &Item);
144
145 fn ready_skip_while<'a, F>(
150 self,
151 f: F,
152 ) -> SkipWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
153 where
154 F: Fn(&Item) -> bool + 'a;
155}
156
157impl<Item, S> ReadyExt<Item> for S
158where
159 S: Stream<Item = Item> + Sized,
160{
161 #[inline]
162 fn ready_all<F>(self, f: F) -> All<Self, Ready<bool>, impl FnMut(Item) -> Ready<bool>>
163 where
164 F: Fn(Item) -> bool,
165 {
166 self.all(move |t| ready(f(t)))
167 }
168
169 #[inline]
170 fn ready_any<F>(self, f: F) -> Any<Self, Ready<bool>, impl FnMut(Item) -> Ready<bool>>
171 where
172 F: Fn(Item) -> bool,
173 {
174 self.any(move |t| ready(f(t)))
175 }
176
177 #[inline]
178 fn ready_find<'a, F>(self, f: F) -> impl Future<Output = Option<Item>> + Send
179 where
180 Self: Send + Unpin + 'a,
181 F: Fn(&Item) -> bool + Send + 'a,
182 Item: Send,
183 {
184 self.ready_filter(f)
185 .take(1)
186 .into_future()
187 .map(|(curr, _next)| curr)
188 }
189
190 #[inline]
191 fn ready_find_map<'a, F, U>(self, f: F) -> impl Future<Output = Option<U>> + Send
192 where
193 Self: Send + Unpin + 'a,
194 F: Fn(Item) -> Option<U> + Send + 'a,
195 Item: Send,
196 U: Send,
197 {
198 self.ready_filter_map(f)
199 .take(1)
200 .into_future()
201 .map(|(curr, _next)| curr)
202 }
203
204 #[inline]
205 fn ready_filter<'a, F>(
206 self,
207 f: F,
208 ) -> Filter<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
209 where
210 F: Fn(&Item) -> bool + 'a,
211 {
212 self.filter(move |t| ready(f(t)))
213 }
214
215 #[inline]
216 fn ready_filter_map<F, U>(
217 self,
218 f: F,
219 ) -> FilterMap<Self, Ready<Option<U>>, impl FnMut(Item) -> Ready<Option<U>>>
220 where
221 F: Fn(Item) -> Option<U>,
222 {
223 self.filter_map(move |t| ready(f(t)))
224 }
225
226 #[inline]
227 fn ready_fold<T, F>(
228 self,
229 init: T,
230 f: F,
231 ) -> Fold<Self, Ready<T>, T, impl FnMut(T, Item) -> Ready<T>>
232 where
233 F: Fn(T, Item) -> T,
234 {
235 self.fold(init, move |a, t| ready(f(a, t)))
236 }
237
238 #[inline]
239 fn ready_fold_default<T, F>(
240 self,
241 f: F,
242 ) -> Fold<Self, Ready<T>, T, impl FnMut(T, Item) -> Ready<T>>
243 where
244 F: Fn(T, Item) -> T,
245 T: Default,
246 {
247 self.ready_fold(T::default(), f)
248 }
249
250 #[inline]
251 #[expect(clippy::unit_arg)]
252 fn ready_for_each<F>(
253 self,
254 mut f: F,
255 ) -> ForEach<Self, Ready<()>, impl FnMut(Item) -> Ready<()>>
256 where
257 F: FnMut(Item),
258 {
259 self.for_each(move |t| ready(f(t)))
260 }
261
262 #[inline]
263 fn ready_take_while<'a, F>(
264 self,
265 f: F,
266 ) -> TakeWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
267 where
268 F: Fn(&Item) -> bool + 'a,
269 {
270 self.take_while(move |t| ready(f(t)))
271 }
272
273 #[inline]
274 fn ready_scan<B, T, F>(
275 self,
276 init: T,
277 f: F,
278 ) -> Scan<Self, T, Ready<Option<B>>, impl FnMut(&mut T, Item) -> Ready<Option<B>>>
279 where
280 F: Fn(&mut T, Item) -> Option<B>,
281 {
282 self.scan(init, move |s, t| ready(f(s, t)))
283 }
284
285 #[inline]
286 fn ready_scan_each<T, F>(
287 self,
288 init: T,
289 f: F,
290 ) -> Scan<Self, T, Ready<Option<Item>>, impl FnMut(&mut T, Item) -> Ready<Option<Item>>>
291 where
292 F: Fn(&mut T, &Item),
293 {
294 self.ready_scan(init, move |s, t| {
295 f(s, &t);
296 Some(t)
297 })
298 }
299
300 #[inline]
301 fn ready_skip_while<'a, F>(
302 self,
303 f: F,
304 ) -> SkipWhile<Self, Ready<bool>, impl FnMut(&Item) -> Ready<bool> + 'a>
305 where
306 F: Fn(&Item) -> bool + 'a,
307 {
308 self.skip_while(move |t| ready(f(t)))
309 }
310}