1 | //! Combinators for the [`Future`] trait. |
2 | //! |
3 | //! # Examples |
4 | //! |
5 | //! ``` |
6 | //! use futures_lite::future; |
7 | //! |
8 | //! # spin_on::spin_on(async { |
9 | //! for step in 0..3 { |
10 | //! println!("step {}" , step); |
11 | //! |
12 | //! // Give other tasks a chance to run. |
13 | //! future::yield_now().await; |
14 | //! } |
15 | //! # }); |
16 | //! ``` |
17 | |
18 | #[cfg (all(not(feature = "std" ), feature = "alloc" ))] |
19 | extern crate alloc; |
20 | |
21 | #[doc (no_inline)] |
22 | pub use core::future::{pending, ready, Future, Pending, Ready}; |
23 | |
24 | use core::fmt; |
25 | use core::pin::Pin; |
26 | |
27 | use pin_project_lite::pin_project; |
28 | |
29 | #[cfg (feature = "std" )] |
30 | use std::{ |
31 | any::Any, |
32 | panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}, |
33 | }; |
34 | |
35 | #[cfg (feature = "race" )] |
36 | use fastrand::Rng; |
37 | |
38 | #[cfg (all(not(feature = "std" ), feature = "alloc" ))] |
39 | use alloc::boxed::Box; |
40 | use core::task::{Context, Poll}; |
41 | |
42 | /// Blocks the current thread on a future. |
43 | /// |
44 | /// # Examples |
45 | /// |
46 | /// ``` |
47 | /// use futures_lite::future; |
48 | /// |
49 | /// let val = future::block_on(async { |
50 | /// 1 + 2 |
51 | /// }); |
52 | /// |
53 | /// assert_eq!(val, 3); |
54 | /// ``` |
55 | #[cfg (feature = "std" )] |
56 | pub fn block_on<T>(future: impl Future<Output = T>) -> T { |
57 | use core::cell::RefCell; |
58 | use core::task::Waker; |
59 | |
60 | use parking::Parker; |
61 | |
62 | // Pin the future on the stack. |
63 | crate::pin!(future); |
64 | |
65 | // Creates a parker and an associated waker that unparks it. |
66 | fn parker_and_waker() -> (Parker, Waker) { |
67 | let parker = Parker::new(); |
68 | let unparker = parker.unparker(); |
69 | let waker = Waker::from(unparker); |
70 | (parker, waker) |
71 | } |
72 | |
73 | thread_local! { |
74 | // Cached parker and waker for efficiency. |
75 | static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker()); |
76 | } |
77 | |
78 | CACHE.with(|cache| { |
79 | // Try grabbing the cached parker and waker. |
80 | let tmp_cached; |
81 | let tmp_fresh; |
82 | let (parker, waker) = match cache.try_borrow_mut() { |
83 | Ok(cache) => { |
84 | // Use the cached parker and waker. |
85 | tmp_cached = cache; |
86 | &*tmp_cached |
87 | } |
88 | Err(_) => { |
89 | // Looks like this is a recursive `block_on()` call. |
90 | // Create a fresh parker and waker. |
91 | tmp_fresh = parker_and_waker(); |
92 | &tmp_fresh |
93 | } |
94 | }; |
95 | |
96 | let cx = &mut Context::from_waker(waker); |
97 | // Keep polling until the future is ready. |
98 | loop { |
99 | match future.as_mut().poll(cx) { |
100 | Poll::Ready(output) => return output, |
101 | Poll::Pending => parker.park(), |
102 | } |
103 | } |
104 | }) |
105 | } |
106 | |
107 | /// Polls a future just once and returns an [`Option`] with the result. |
108 | /// |
109 | /// # Examples |
110 | /// |
111 | /// ``` |
112 | /// use futures_lite::future; |
113 | /// |
114 | /// # spin_on::spin_on(async { |
115 | /// assert_eq!(future::poll_once(future::pending::<()>()).await, None); |
116 | /// assert_eq!(future::poll_once(future::ready(42)).await, Some(42)); |
117 | /// # }) |
118 | /// ``` |
119 | pub fn poll_once<T, F>(f: F) -> PollOnce<F> |
120 | where |
121 | F: Future<Output = T>, |
122 | { |
123 | PollOnce { f } |
124 | } |
125 | |
126 | pin_project! { |
127 | /// Future for the [`poll_once()`] function. |
128 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
129 | pub struct PollOnce<F> { |
130 | #[pin] |
131 | f: F, |
132 | } |
133 | } |
134 | |
135 | impl<F> fmt::Debug for PollOnce<F> { |
136 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
137 | f.debug_struct(name:"PollOnce" ).finish() |
138 | } |
139 | } |
140 | |
141 | impl<T, F> Future for PollOnce<F> |
142 | where |
143 | F: Future<Output = T>, |
144 | { |
145 | type Output = Option<T>; |
146 | |
147 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
148 | match self.project().f.poll(cx) { |
149 | Poll::Ready(t: T) => Poll::Ready(Some(t)), |
150 | Poll::Pending => Poll::Ready(None), |
151 | } |
152 | } |
153 | } |
154 | |
155 | /// Creates a future from a function returning [`Poll`]. |
156 | /// |
157 | /// # Examples |
158 | /// |
159 | /// ``` |
160 | /// use futures_lite::future; |
161 | /// use std::task::{Context, Poll}; |
162 | /// |
163 | /// # spin_on::spin_on(async { |
164 | /// fn f(_: &mut Context<'_>) -> Poll<i32> { |
165 | /// Poll::Ready(7) |
166 | /// } |
167 | /// |
168 | /// assert_eq!(future::poll_fn(f).await, 7); |
169 | /// # }) |
170 | /// ``` |
171 | pub fn poll_fn<T, F>(f: F) -> PollFn<F> |
172 | where |
173 | F: FnMut(&mut Context<'_>) -> Poll<T>, |
174 | { |
175 | PollFn { f } |
176 | } |
177 | |
178 | pin_project! { |
179 | /// Future for the [`poll_fn()`] function. |
180 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
181 | pub struct PollFn<F> { |
182 | f: F, |
183 | } |
184 | } |
185 | |
186 | impl<F> fmt::Debug for PollFn<F> { |
187 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
188 | f.debug_struct(name:"PollFn" ).finish() |
189 | } |
190 | } |
191 | |
192 | impl<T, F> Future for PollFn<F> |
193 | where |
194 | F: FnMut(&mut Context<'_>) -> Poll<T>, |
195 | { |
196 | type Output = T; |
197 | |
198 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> { |
199 | let this: Projection<'_, F> = self.project(); |
200 | (this.f)(cx) |
201 | } |
202 | } |
203 | |
204 | /// Wakes the current task and returns [`Poll::Pending`] once. |
205 | /// |
206 | /// This function is useful when we want to cooperatively give time to the task scheduler. It is |
207 | /// generally a good idea to yield inside loops because that way we make sure long-running tasks |
208 | /// don't prevent other tasks from running. |
209 | /// |
210 | /// # Examples |
211 | /// |
212 | /// ``` |
213 | /// use futures_lite::future; |
214 | /// |
215 | /// # spin_on::spin_on(async { |
216 | /// future::yield_now().await; |
217 | /// # }) |
218 | /// ``` |
219 | pub fn yield_now() -> YieldNow { |
220 | YieldNow(false) |
221 | } |
222 | |
223 | /// Future for the [`yield_now()`] function. |
224 | #[derive (Debug)] |
225 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
226 | pub struct YieldNow(bool); |
227 | |
228 | impl Future for YieldNow { |
229 | type Output = (); |
230 | |
231 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
232 | if !self.0 { |
233 | self.0 = true; |
234 | cx.waker().wake_by_ref(); |
235 | Poll::Pending |
236 | } else { |
237 | Poll::Ready(()) |
238 | } |
239 | } |
240 | } |
241 | |
242 | /// Joins two futures, waiting for both to complete. |
243 | /// |
244 | /// # Examples |
245 | /// |
246 | /// ``` |
247 | /// use futures_lite::future; |
248 | /// |
249 | /// # spin_on::spin_on(async { |
250 | /// let a = async { 1 }; |
251 | /// let b = async { 2 }; |
252 | /// |
253 | /// assert_eq!(future::zip(a, b).await, (1, 2)); |
254 | /// # }) |
255 | /// ``` |
256 | pub fn zip<F1, F2>(future1: F1, future2: F2) -> Zip<F1, F2> |
257 | where |
258 | F1: Future, |
259 | F2: Future, |
260 | { |
261 | Zip { |
262 | future1, |
263 | future2, |
264 | output1: None, |
265 | output2: None, |
266 | } |
267 | } |
268 | |
269 | pin_project! { |
270 | /// Future for the [`zip()`] function. |
271 | #[derive(Debug)] |
272 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
273 | pub struct Zip<F1, F2> |
274 | where |
275 | F1: Future, |
276 | F2: Future, |
277 | { |
278 | #[pin] |
279 | future1: F1, |
280 | output1: Option<F1::Output>, |
281 | #[pin] |
282 | future2: F2, |
283 | output2: Option<F2::Output>, |
284 | } |
285 | } |
286 | |
287 | /// Extracts the contents of two options and zips them, handling `(Some(_), None)` cases |
288 | fn take_zip_from_parts<T1, T2>(o1: &mut Option<T1>, o2: &mut Option<T2>) -> Poll<(T1, T2)> { |
289 | match (o1.take(), o2.take()) { |
290 | (Some(t1: T1), Some(t2: T2)) => Poll::Ready((t1, t2)), |
291 | (o1x: Option, o2x: Option) => { |
292 | *o1 = o1x; |
293 | *o2 = o2x; |
294 | Poll::Pending |
295 | } |
296 | } |
297 | } |
298 | |
299 | impl<F1, F2> Future for Zip<F1, F2> |
300 | where |
301 | F1: Future, |
302 | F2: Future, |
303 | { |
304 | type Output = (F1::Output, F2::Output); |
305 | |
306 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
307 | let this: Projection<'_, F1, F2> = self.project(); |
308 | |
309 | if this.output1.is_none() { |
310 | if let Poll::Ready(out: ::Output) = this.future1.poll(cx) { |
311 | *this.output1 = Some(out); |
312 | } |
313 | } |
314 | |
315 | if this.output2.is_none() { |
316 | if let Poll::Ready(out: ::Output) = this.future2.poll(cx) { |
317 | *this.output2 = Some(out); |
318 | } |
319 | } |
320 | |
321 | take_zip_from_parts(o1:this.output1, o2:this.output2) |
322 | } |
323 | } |
324 | |
325 | /// Joins two fallible futures, waiting for both to complete or one of them to error. |
326 | /// |
327 | /// # Examples |
328 | /// |
329 | /// ``` |
330 | /// use futures_lite::future; |
331 | /// |
332 | /// # spin_on::spin_on(async { |
333 | /// let a = async { Ok::<i32, i32>(1) }; |
334 | /// let b = async { Err::<i32, i32>(2) }; |
335 | /// |
336 | /// assert_eq!(future::try_zip(a, b).await, Err(2)); |
337 | /// # }) |
338 | /// ``` |
339 | pub fn try_zip<T1, T2, E, F1, F2>(future1: F1, future2: F2) -> TryZip<F1, T1, F2, T2> |
340 | where |
341 | F1: Future<Output = Result<T1, E>>, |
342 | F2: Future<Output = Result<T2, E>>, |
343 | { |
344 | TryZip { |
345 | future1, |
346 | future2, |
347 | output1: None, |
348 | output2: None, |
349 | } |
350 | } |
351 | |
352 | pin_project! { |
353 | /// Future for the [`try_zip()`] function. |
354 | #[derive(Debug)] |
355 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
356 | pub struct TryZip<F1, T1, F2, T2> { |
357 | #[pin] |
358 | future1: F1, |
359 | output1: Option<T1>, |
360 | #[pin] |
361 | future2: F2, |
362 | output2: Option<T2>, |
363 | } |
364 | } |
365 | |
366 | impl<T1, T2, E, F1, F2> Future for TryZip<F1, T1, F2, T2> |
367 | where |
368 | F1: Future<Output = Result<T1, E>>, |
369 | F2: Future<Output = Result<T2, E>>, |
370 | { |
371 | type Output = Result<(T1, T2), E>; |
372 | |
373 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
374 | let this = self.project(); |
375 | |
376 | if this.output1.is_none() { |
377 | if let Poll::Ready(out) = this.future1.poll(cx) { |
378 | match out { |
379 | Ok(t) => *this.output1 = Some(t), |
380 | Err(err) => return Poll::Ready(Err(err)), |
381 | } |
382 | } |
383 | } |
384 | |
385 | if this.output2.is_none() { |
386 | if let Poll::Ready(out) = this.future2.poll(cx) { |
387 | match out { |
388 | Ok(t) => *this.output2 = Some(t), |
389 | Err(err) => return Poll::Ready(Err(err)), |
390 | } |
391 | } |
392 | } |
393 | |
394 | take_zip_from_parts(this.output1, this.output2).map(Ok) |
395 | } |
396 | } |
397 | |
398 | /// Returns the result of the future that completes first, preferring `future1` if both are ready. |
399 | /// |
400 | /// If you need to treat the two futures fairly without a preference for either, use the [`race()`] |
401 | /// function or the [`FutureExt::race()`] method. |
402 | /// |
403 | /// # Examples |
404 | /// |
405 | /// ``` |
406 | /// use futures_lite::future::{self, pending, ready}; |
407 | /// |
408 | /// # spin_on::spin_on(async { |
409 | /// assert_eq!(future::or(ready(1), pending()).await, 1); |
410 | /// assert_eq!(future::or(pending(), ready(2)).await, 2); |
411 | /// |
412 | /// // The first future wins. |
413 | /// assert_eq!(future::or(ready(1), ready(2)).await, 1); |
414 | /// # }) |
415 | /// ``` |
416 | pub fn or<T, F1, F2>(future1: F1, future2: F2) -> Or<F1, F2> |
417 | where |
418 | F1: Future<Output = T>, |
419 | F2: Future<Output = T>, |
420 | { |
421 | Or { future1, future2 } |
422 | } |
423 | |
424 | pin_project! { |
425 | /// Future for the [`or()`] function and the [`FutureExt::or()`] method. |
426 | #[derive(Debug)] |
427 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
428 | pub struct Or<F1, F2> { |
429 | #[pin] |
430 | future1: F1, |
431 | #[pin] |
432 | future2: F2, |
433 | } |
434 | } |
435 | |
436 | impl<T, F1, F2> Future for Or<F1, F2> |
437 | where |
438 | F1: Future<Output = T>, |
439 | F2: Future<Output = T>, |
440 | { |
441 | type Output = T; |
442 | |
443 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
444 | let this: Projection<'_, F1, F2> = self.project(); |
445 | |
446 | if let Poll::Ready(t: T) = this.future1.poll(cx) { |
447 | return Poll::Ready(t); |
448 | } |
449 | if let Poll::Ready(t: T) = this.future2.poll(cx) { |
450 | return Poll::Ready(t); |
451 | } |
452 | Poll::Pending |
453 | } |
454 | } |
455 | |
456 | /// Returns the result of the future that completes first, with no preference if both are ready. |
457 | /// |
458 | /// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore, no |
459 | /// future takes precedence over the other if both can complete at the same time. |
460 | /// |
461 | /// If you have preference for one of the futures, use the [`or()`] function or the |
462 | /// [`FutureExt::or()`] method. |
463 | /// |
464 | /// # Examples |
465 | /// |
466 | /// ``` |
467 | /// use futures_lite::future::{self, pending, ready}; |
468 | /// |
469 | /// # spin_on::spin_on(async { |
470 | /// assert_eq!(future::race(ready(1), pending()).await, 1); |
471 | /// assert_eq!(future::race(pending(), ready(2)).await, 2); |
472 | /// |
473 | /// // One of the two futures is randomly chosen as the winner. |
474 | /// let res = future::race(ready(1), ready(2)).await; |
475 | /// # }) |
476 | /// ``` |
477 | #[cfg (all(feature = "race" , feature = "std" ))] |
478 | pub fn race<T, F1, F2>(future1: F1, future2: F2) -> Race<F1, F2> |
479 | where |
480 | F1: Future<Output = T>, |
481 | F2: Future<Output = T>, |
482 | { |
483 | Race { |
484 | future1, |
485 | future2, |
486 | rng: Rng::new(), |
487 | } |
488 | } |
489 | |
490 | /// Race two futures but with a predefined random seed. |
491 | /// |
492 | /// This function is identical to [`race`], but instead of using a random seed from a thread-local |
493 | /// RNG, it allows the user to provide a seed. It is useful for when you already have a source of |
494 | /// randomness available, or if you want to use a fixed seed. |
495 | /// |
496 | /// See documentation of the [`race`] function for features and caveats. |
497 | /// |
498 | /// # Examples |
499 | /// |
500 | /// ``` |
501 | /// use futures_lite::future::{self, pending, ready}; |
502 | /// |
503 | /// // A fixed seed is used, so the result is deterministic. |
504 | /// const SEED: u64 = 0x42; |
505 | /// |
506 | /// # spin_on::spin_on(async { |
507 | /// assert_eq!(future::race_with_seed(ready(1), pending(), SEED).await, 1); |
508 | /// assert_eq!(future::race_with_seed(pending(), ready(2), SEED).await, 2); |
509 | /// |
510 | /// // One of the two futures is randomly chosen as the winner. |
511 | /// let res = future::race_with_seed(ready(1), ready(2), SEED).await; |
512 | /// # }) |
513 | /// ``` |
514 | #[cfg (feature = "race" )] |
515 | pub fn race_with_seed<T, F1, F2>(future1: F1, future2: F2, seed: u64) -> Race<F1, F2> |
516 | where |
517 | F1: Future<Output = T>, |
518 | F2: Future<Output = T>, |
519 | { |
520 | Race { |
521 | future1, |
522 | future2, |
523 | rng: Rng::with_seed(seed), |
524 | } |
525 | } |
526 | |
527 | #[cfg (feature = "race" )] |
528 | pin_project! { |
529 | /// Future for the [`race()`] function and the [`FutureExt::race()`] method. |
530 | #[derive(Debug)] |
531 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
532 | pub struct Race<F1, F2> { |
533 | #[pin] |
534 | future1: F1, |
535 | #[pin] |
536 | future2: F2, |
537 | rng: Rng, |
538 | } |
539 | } |
540 | |
541 | #[cfg (feature = "race" )] |
542 | impl<T, F1, F2> Future for Race<F1, F2> |
543 | where |
544 | F1: Future<Output = T>, |
545 | F2: Future<Output = T>, |
546 | { |
547 | type Output = T; |
548 | |
549 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
550 | let this: Projection<'_, F1, F2> = self.project(); |
551 | |
552 | if this.rng.bool() { |
553 | if let Poll::Ready(t: T) = this.future1.poll(cx) { |
554 | return Poll::Ready(t); |
555 | } |
556 | if let Poll::Ready(t: T) = this.future2.poll(cx) { |
557 | return Poll::Ready(t); |
558 | } |
559 | } else { |
560 | if let Poll::Ready(t: T) = this.future2.poll(cx) { |
561 | return Poll::Ready(t); |
562 | } |
563 | if let Poll::Ready(t: T) = this.future1.poll(cx) { |
564 | return Poll::Ready(t); |
565 | } |
566 | } |
567 | Poll::Pending |
568 | } |
569 | } |
570 | |
571 | #[cfg (feature = "std" )] |
572 | pin_project! { |
573 | /// Future for the [`FutureExt::catch_unwind()`] method. |
574 | #[derive(Debug)] |
575 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
576 | pub struct CatchUnwind<F> { |
577 | #[pin] |
578 | inner: F, |
579 | } |
580 | } |
581 | |
582 | #[cfg (feature = "std" )] |
583 | impl<F: Future + UnwindSafe> Future for CatchUnwind<F> { |
584 | type Output = Result<F::Output, Box<dyn Any + Send>>; |
585 | |
586 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
587 | let this: Projection<'_, F> = self.project(); |
588 | catch_unwind(AssertUnwindSafe(|| this.inner.poll(cx)))?.map(Ok) |
589 | } |
590 | } |
591 | |
592 | /// Type alias for `Pin<Box<dyn Future<Output = T> + Send + 'static>>`. |
593 | /// |
594 | /// # Examples |
595 | /// |
596 | /// ``` |
597 | /// use futures_lite::future::{self, FutureExt}; |
598 | /// |
599 | /// // These two lines are equivalent: |
600 | /// let f1: future::Boxed<i32> = async { 1 + 2 }.boxed(); |
601 | /// let f2: future::Boxed<i32> = Box::pin(async { 1 + 2 }); |
602 | /// ``` |
603 | #[cfg (feature = "alloc" )] |
604 | pub type Boxed<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>; |
605 | |
606 | /// Type alias for `Pin<Box<dyn Future<Output = T> + 'static>>`. |
607 | /// |
608 | /// # Examples |
609 | /// |
610 | /// ``` |
611 | /// use futures_lite::future::{self, FutureExt}; |
612 | /// |
613 | /// // These two lines are equivalent: |
614 | /// let f1: future::BoxedLocal<i32> = async { 1 + 2 }.boxed_local(); |
615 | /// let f2: future::BoxedLocal<i32> = Box::pin(async { 1 + 2 }); |
616 | /// ``` |
617 | #[cfg (feature = "alloc" )] |
618 | pub type BoxedLocal<T> = Pin<Box<dyn Future<Output = T> + 'static>>; |
619 | |
620 | /// Extension trait for [`Future`]. |
621 | pub trait FutureExt: Future { |
622 | /// A convenience for calling [`Future::poll()`] on `!`[`Unpin`] types. |
623 | fn poll(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output> |
624 | where |
625 | Self: Unpin, |
626 | { |
627 | Future::poll(Pin::new(self), cx) |
628 | } |
629 | |
630 | /// Returns the result of `self` or `other` future, preferring `self` if both are ready. |
631 | /// |
632 | /// If you need to treat the two futures fairly without a preference for either, use the |
633 | /// [`race()`] function or the [`FutureExt::race()`] method. |
634 | /// |
635 | /// # Examples |
636 | /// |
637 | /// ``` |
638 | /// use futures_lite::future::{pending, ready, FutureExt}; |
639 | /// |
640 | /// # spin_on::spin_on(async { |
641 | /// assert_eq!(ready(1).or(pending()).await, 1); |
642 | /// assert_eq!(pending().or(ready(2)).await, 2); |
643 | /// |
644 | /// // The first future wins. |
645 | /// assert_eq!(ready(1).or(ready(2)).await, 1); |
646 | /// # }) |
647 | /// ``` |
648 | fn or<F>(self, other: F) -> Or<Self, F> |
649 | where |
650 | Self: Sized, |
651 | F: Future<Output = Self::Output>, |
652 | { |
653 | Or { |
654 | future1: self, |
655 | future2: other, |
656 | } |
657 | } |
658 | |
659 | /// Returns the result of `self` or `other` future, with no preference if both are ready. |
660 | /// |
661 | /// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore, |
662 | /// no future takes precedence over the other if both can complete at the same time. |
663 | /// |
664 | /// If you have preference for one of the futures, use the [`or()`] function or the |
665 | /// [`FutureExt::or()`] method. |
666 | /// |
667 | /// # Examples |
668 | /// |
669 | /// ``` |
670 | /// use futures_lite::future::{pending, ready, FutureExt}; |
671 | /// |
672 | /// # spin_on::spin_on(async { |
673 | /// assert_eq!(ready(1).race(pending()).await, 1); |
674 | /// assert_eq!(pending().race(ready(2)).await, 2); |
675 | /// |
676 | /// // One of the two futures is randomly chosen as the winner. |
677 | /// let res = ready(1).race(ready(2)).await; |
678 | /// # }) |
679 | /// ``` |
680 | #[cfg (all(feature = "std" , feature = "race" ))] |
681 | fn race<F>(self, other: F) -> Race<Self, F> |
682 | where |
683 | Self: Sized, |
684 | F: Future<Output = Self::Output>, |
685 | { |
686 | Race { |
687 | future1: self, |
688 | future2: other, |
689 | rng: Rng::new(), |
690 | } |
691 | } |
692 | |
693 | /// Catches panics while polling the future. |
694 | /// |
695 | /// # Examples |
696 | /// |
697 | /// ``` |
698 | /// use futures_lite::future::FutureExt; |
699 | /// |
700 | /// # spin_on::spin_on(async { |
701 | /// let fut1 = async {}.catch_unwind(); |
702 | /// let fut2 = async { panic!() }.catch_unwind(); |
703 | /// |
704 | /// assert!(fut1.await.is_ok()); |
705 | /// assert!(fut2.await.is_err()); |
706 | /// # }) |
707 | /// ``` |
708 | #[cfg (feature = "std" )] |
709 | fn catch_unwind(self) -> CatchUnwind<Self> |
710 | where |
711 | Self: Sized + UnwindSafe, |
712 | { |
713 | CatchUnwind { inner: self } |
714 | } |
715 | |
716 | /// Boxes the future and changes its type to `dyn Future + Send + 'a`. |
717 | /// |
718 | /// # Examples |
719 | /// |
720 | /// ``` |
721 | /// use futures_lite::future::{self, FutureExt}; |
722 | /// |
723 | /// # spin_on::spin_on(async { |
724 | /// let a = future::ready('a' ); |
725 | /// let b = future::pending(); |
726 | /// |
727 | /// // Futures of different types can be stored in |
728 | /// // the same collection when they are boxed: |
729 | /// let futures = vec![a.boxed(), b.boxed()]; |
730 | /// # }) |
731 | /// ``` |
732 | #[cfg (feature = "alloc" )] |
733 | fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>> |
734 | where |
735 | Self: Sized + Send + 'a, |
736 | { |
737 | Box::pin(self) |
738 | } |
739 | |
740 | /// Boxes the future and changes its type to `dyn Future + 'a`. |
741 | /// |
742 | /// # Examples |
743 | /// |
744 | /// ``` |
745 | /// use futures_lite::future::{self, FutureExt}; |
746 | /// |
747 | /// # spin_on::spin_on(async { |
748 | /// let a = future::ready('a' ); |
749 | /// let b = future::pending(); |
750 | /// |
751 | /// // Futures of different types can be stored in |
752 | /// // the same collection when they are boxed: |
753 | /// let futures = vec![a.boxed_local(), b.boxed_local()]; |
754 | /// # }) |
755 | /// ``` |
756 | #[cfg (feature = "alloc" )] |
757 | fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>> |
758 | where |
759 | Self: Sized + 'a, |
760 | { |
761 | Box::pin(self) |
762 | } |
763 | } |
764 | |
765 | impl<F: Future + ?Sized> FutureExt for F {} |
766 | |