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" )] |
19 | extern crate alloc; |
20 | |
21 | #[doc (no_inline)] |
22 | pub use core::future::Future; |
23 | |
24 | use core::fmt; |
25 | use core::marker::PhantomData; |
26 | use core::pin::Pin; |
27 | |
28 | use pin_project_lite::pin_project; |
29 | |
30 | #[cfg (feature = "std" )] |
31 | use std::{ |
32 | any::Any, |
33 | panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}, |
34 | }; |
35 | |
36 | #[cfg (feature = "alloc" )] |
37 | use alloc::boxed::Box; |
38 | use 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" )] |
54 | pub 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 | /// ``` |
125 | pub 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" ] |
133 | pub struct Pending<T> { |
134 | _marker: PhantomData<T>, |
135 | } |
136 | |
137 | impl<T> Unpin for Pending<T> {} |
138 | |
139 | impl<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 | |
145 | impl<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 | /// ``` |
165 | pub fn poll_once<T, F>(f: F) -> PollOnce<F> |
166 | where |
167 | F: Future<Output = T>, |
168 | { |
169 | PollOnce { f } |
170 | } |
171 | |
172 | pin_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 | |
181 | impl<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 | |
187 | impl<T, F> Future for PollOnce<F> |
188 | where |
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 | /// ``` |
217 | pub fn poll_fn<T, F>(f: F) -> PollFn<F> |
218 | where |
219 | F: FnMut(&mut Context<'_>) -> Poll<T>, |
220 | { |
221 | PollFn { f } |
222 | } |
223 | |
224 | pin_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 | |
232 | impl<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 | |
238 | impl<T, F> Future for PollFn<F> |
239 | where |
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 | /// ``` |
261 | pub 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" ] |
268 | pub struct Ready<T>(Option<T>); |
269 | |
270 | impl<T> Unpin for Ready<T> {} |
271 | |
272 | impl<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 | /// ``` |
295 | pub 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" ] |
302 | pub struct YieldNow(bool); |
303 | |
304 | impl 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 | /// ``` |
332 | pub fn zip<F1, F2>(future1: F1, future2: F2) -> Zip<F1, F2> |
333 | where |
334 | F1: Future, |
335 | F2: Future, |
336 | { |
337 | Zip { |
338 | future1, |
339 | future2, |
340 | output1: None, |
341 | output2: None, |
342 | } |
343 | } |
344 | |
345 | pin_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 | |
363 | impl<F1, F2> Future for Zip<F1, F2> |
364 | where |
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 | /// ``` |
407 | pub fn try_zip<T1, T2, E, F1, F2>(future1: F1, future2: F2) -> TryZip<F1, F2> |
408 | where |
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 | |
420 | pin_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 | |
438 | impl<T1, T2, E, F1, F2> Future for TryZip<F1, F2> |
439 | where |
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 | /// ``` |
496 | pub fn or<T, F1, F2>(future1: F1, future2: F2) -> Or<F1, F2> |
497 | where |
498 | F1: Future<Output = T>, |
499 | F2: Future<Output = T>, |
500 | { |
501 | Or { future1, future2 } |
502 | } |
503 | |
504 | pin_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 | |
516 | impl<T, F1, F2> Future for Or<F1, F2> |
517 | where |
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" )] |
558 | pub fn race<T, F1, F2>(future1: F1, future2: F2) -> Race<F1, F2> |
559 | where |
560 | F1: Future<Output = T>, |
561 | F2: Future<Output = T>, |
562 | { |
563 | Race { future1, future2 } |
564 | } |
565 | |
566 | #[cfg (feature = "std" )] |
567 | pin_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" )] |
580 | impl<T, F1, F2> Future for Race<F1, F2> |
581 | where |
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" )] |
610 | pin_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" )] |
621 | impl<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" )] |
642 | pub 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" )] |
656 | pub type BoxedLocal<T> = Pin<Box<dyn Future<Output = T> + 'static>>; |
657 | |
658 | /// Extension trait for [`Future`]. |
659 | pub 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 | |
802 | impl<F: Future + ?Sized> FutureExt for F {} |
803 | |