futures_lite/
future.rs

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