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(name:"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(name:"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: 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(name:"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: Projection<'_, F> = 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(msg:"`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,
339 future2,
340 output1: None,
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,
414 future2,
415 output1: None,
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: Projection<'_, F1, F2> = self.project();
525
526 if let Poll::Ready(t: T) = this.future1.poll(cx) {
527 return Poll::Ready(t);
528 }
529 if let Poll::Ready(t: 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: Projection<'_, F1, F2> = self.project();
589
590 if fastrand::bool() {
591 if let Poll::Ready(t: T) = this.future1.poll(cx) {
592 return Poll::Ready(t);
593 }
594 if let Poll::Ready(t: T) = this.future2.poll(cx) {
595 return Poll::Ready(t);
596 }
597 } else {
598 if let Poll::Ready(t: T) = this.future2.poll(cx) {
599 return Poll::Ready(t);
600 }
601 if let Poll::Ready(t: 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: Projection<'_, F> = 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 {}
803