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"))]
19extern crate alloc;
20
21#[doc(no_inline)]
22pub use core::future::{pending, ready, Future, Pending, Ready};
23
24use core::fmt;
25use core::pin::Pin;
26
27use pin_project_lite::pin_project;
28
29#[cfg(feature = "std")]
30use std::{
31 any::Any,
32 panic::{catch_unwind, AssertUnwindSafe, UnwindSafe},
33};
34
35#[cfg(feature = "race")]
36use fastrand::Rng;
37
38#[cfg(all(not(feature = "std"), feature = "alloc"))]
39use alloc::boxed::Box;
40use 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")]
56pub 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/// ```
119pub fn poll_once<T, F>(f: F) -> PollOnce<F>
120where
121 F: Future<Output = T>,
122{
123 PollOnce { f }
124}
125
126pin_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
135impl<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
141impl<T, F> Future for PollOnce<F>
142where
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/// ```
171pub fn poll_fn<T, F>(f: F) -> PollFn<F>
172where
173 F: FnMut(&mut Context<'_>) -> Poll<T>,
174{
175 PollFn { f }
176}
177
178pin_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
186impl<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
192impl<T, F> Future for PollFn<F>
193where
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/// ```
219pub 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"]
226pub struct YieldNow(bool);
227
228impl 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/// ```
256pub fn zip<F1, F2>(future1: F1, future2: F2) -> Zip<F1, F2>
257where
258 F1: Future,
259 F2: Future,
260{
261 Zip {
262 future1,
263 future2,
264 output1: None,
265 output2: None,
266 }
267}
268
269pin_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
288fn 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
299impl<F1, F2> Future for Zip<F1, F2>
300where
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/// ```
339pub fn try_zip<T1, T2, E, F1, F2>(future1: F1, future2: F2) -> TryZip<F1, T1, F2, T2>
340where
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
352pin_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
366impl<T1, T2, E, F1, F2> Future for TryZip<F1, T1, F2, T2>
367where
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/// ```
416pub fn or<T, F1, F2>(future1: F1, future2: F2) -> Or<F1, F2>
417where
418 F1: Future<Output = T>,
419 F2: Future<Output = T>,
420{
421 Or { future1, future2 }
422}
423
424pin_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
436impl<T, F1, F2> Future for Or<F1, F2>
437where
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"))]
478pub fn race<T, F1, F2>(future1: F1, future2: F2) -> Race<F1, F2>
479where
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")]
515pub fn race_with_seed<T, F1, F2>(future1: F1, future2: F2, seed: u64) -> Race<F1, F2>
516where
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")]
528pin_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")]
542impl<T, F1, F2> Future for Race<F1, F2>
543where
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")]
572pin_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")]
583impl<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")]
604pub 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")]
618pub type BoxedLocal<T> = Pin<Box<dyn Future<Output = T> + 'static>>;
619
620/// Extension trait for [`Future`].
621pub 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
765impl<F: Future + ?Sized> FutureExt for F {}
766