| 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: Some(future1), |
| 263 | future2: Some(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: Option<F1>, |
| 280 | output1: Option<F1::Output>, |
| 281 | #[pin] |
| 282 | future2: Option<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 mut this: Projection<'_, F1, F2> = self.project(); |
| 308 | |
| 309 | if let Some(future: Pin<&mut F1>) = this.future1.as_mut().as_pin_mut() { |
| 310 | if let Poll::Ready(out: ::Output) = future.poll(cx) { |
| 311 | *this.output1 = Some(out); |
| 312 | this.future1.set(None); |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | if let Some(future: Pin<&mut F2>) = this.future2.as_mut().as_pin_mut() { |
| 317 | if let Poll::Ready(out: ::Output) = future.poll(cx) { |
| 318 | *this.output2 = Some(out); |
| 319 | this.future2.set(None); |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | take_zip_from_parts(o1:this.output1, o2:this.output2) |
| 324 | } |
| 325 | } |
| 326 | |
| 327 | /// Joins two fallible futures, waiting for both to complete or one of them to error. |
| 328 | /// |
| 329 | /// # Examples |
| 330 | /// |
| 331 | /// ``` |
| 332 | /// use futures_lite::future; |
| 333 | /// |
| 334 | /// # spin_on::spin_on(async { |
| 335 | /// let a = async { Ok::<i32, i32>(1) }; |
| 336 | /// let b = async { Err::<i32, i32>(2) }; |
| 337 | /// |
| 338 | /// assert_eq!(future::try_zip(a, b).await, Err(2)); |
| 339 | /// # }) |
| 340 | /// ``` |
| 341 | pub fn try_zip<T1, T2, E, F1, F2>(future1: F1, future2: F2) -> TryZip<F1, T1, F2, T2> |
| 342 | where |
| 343 | F1: Future<Output = Result<T1, E>>, |
| 344 | F2: Future<Output = Result<T2, E>>, |
| 345 | { |
| 346 | TryZip { |
| 347 | future1: Some(future1), |
| 348 | future2: Some(future2), |
| 349 | output1: None, |
| 350 | output2: None, |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | pin_project! { |
| 355 | /// Future for the [`try_zip()`] function. |
| 356 | #[derive (Debug)] |
| 357 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
| 358 | pub struct TryZip<F1, T1, F2, T2> { |
| 359 | #[pin] |
| 360 | future1: Option<F1>, |
| 361 | output1: Option<T1>, |
| 362 | #[pin] |
| 363 | future2: Option<F2>, |
| 364 | output2: Option<T2>, |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | impl<T1, T2, E, F1, F2> Future for TryZip<F1, T1, F2, T2> |
| 369 | where |
| 370 | F1: Future<Output = Result<T1, E>>, |
| 371 | F2: Future<Output = Result<T2, E>>, |
| 372 | { |
| 373 | type Output = Result<(T1, T2), E>; |
| 374 | |
| 375 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 376 | let mut this = self.project(); |
| 377 | |
| 378 | if let Some(future) = this.future1.as_mut().as_pin_mut() { |
| 379 | if let Poll::Ready(out) = future.poll(cx) { |
| 380 | match out { |
| 381 | Ok(t) => { |
| 382 | *this.output1 = Some(t); |
| 383 | this.future1.set(None); |
| 384 | } |
| 385 | Err(err) => return Poll::Ready(Err(err)), |
| 386 | } |
| 387 | } |
| 388 | } |
| 389 | |
| 390 | if let Some(future) = this.future2.as_mut().as_pin_mut() { |
| 391 | if let Poll::Ready(out) = future.poll(cx) { |
| 392 | match out { |
| 393 | Ok(t) => { |
| 394 | *this.output2 = Some(t); |
| 395 | this.future2.set(None); |
| 396 | } |
| 397 | Err(err) => return Poll::Ready(Err(err)), |
| 398 | } |
| 399 | } |
| 400 | } |
| 401 | |
| 402 | take_zip_from_parts(this.output1, this.output2).map(Ok) |
| 403 | } |
| 404 | } |
| 405 | |
| 406 | /// Returns the result of the future that completes first, preferring `future1` if both are ready. |
| 407 | /// |
| 408 | /// If you need to treat the two futures fairly without a preference for either, use the [`race()`] |
| 409 | /// function or the [`FutureExt::race()`] method. |
| 410 | /// |
| 411 | /// # Examples |
| 412 | /// |
| 413 | /// ``` |
| 414 | /// use futures_lite::future::{self, pending, ready}; |
| 415 | /// |
| 416 | /// # spin_on::spin_on(async { |
| 417 | /// assert_eq!(future::or(ready(1), pending()).await, 1); |
| 418 | /// assert_eq!(future::or(pending(), ready(2)).await, 2); |
| 419 | /// |
| 420 | /// // The first future wins. |
| 421 | /// assert_eq!(future::or(ready(1), ready(2)).await, 1); |
| 422 | /// # }) |
| 423 | /// ``` |
| 424 | pub fn or<T, F1, F2>(future1: F1, future2: F2) -> Or<F1, F2> |
| 425 | where |
| 426 | F1: Future<Output = T>, |
| 427 | F2: Future<Output = T>, |
| 428 | { |
| 429 | Or { future1, future2 } |
| 430 | } |
| 431 | |
| 432 | pin_project! { |
| 433 | /// Future for the [`or()`] function and the [`FutureExt::or()`] method. |
| 434 | #[derive (Debug)] |
| 435 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
| 436 | pub struct Or<F1, F2> { |
| 437 | #[pin] |
| 438 | future1: F1, |
| 439 | #[pin] |
| 440 | future2: F2, |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | impl<T, F1, F2> Future for Or<F1, F2> |
| 445 | where |
| 446 | F1: Future<Output = T>, |
| 447 | F2: Future<Output = T>, |
| 448 | { |
| 449 | type Output = T; |
| 450 | |
| 451 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 452 | let this: Projection<'_, F1, F2> = self.project(); |
| 453 | |
| 454 | if let Poll::Ready(t: T) = this.future1.poll(cx) { |
| 455 | return Poll::Ready(t); |
| 456 | } |
| 457 | if let Poll::Ready(t: T) = this.future2.poll(cx) { |
| 458 | return Poll::Ready(t); |
| 459 | } |
| 460 | Poll::Pending |
| 461 | } |
| 462 | } |
| 463 | |
| 464 | /// Fuse a future such that `poll` will never again be called once it has |
| 465 | /// completed. This method can be used to turn any `Future` into a |
| 466 | /// `FusedFuture`. |
| 467 | /// |
| 468 | /// Normally, once a future has returned `Poll::Ready` from `poll`, |
| 469 | /// any further calls could exhibit bad behavior such as blocking |
| 470 | /// forever, panicking, never returning, etc. If it is known that `poll` |
| 471 | /// may be called too often then this method can be used to ensure that it |
| 472 | /// has defined semantics. |
| 473 | /// |
| 474 | /// If a `fuse`d future is `poll`ed after having returned `Poll::Ready` |
| 475 | /// previously, it will return `Poll::Pending`, from `poll` again (and will |
| 476 | /// continue to do so for all future calls to `poll`). |
| 477 | /// |
| 478 | /// This combinator will drop the underlying future as soon as it has been |
| 479 | /// completed to ensure resources are reclaimed as soon as possible. |
| 480 | pub fn fuse<F>(future: F) -> Fuse<F> |
| 481 | where |
| 482 | F: Future + Sized, |
| 483 | { |
| 484 | Fuse::new(future) |
| 485 | } |
| 486 | |
| 487 | pin_project! { |
| 488 | /// [`Future`] for the [`fuse`] method. |
| 489 | #[derive (Debug)] |
| 490 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
| 491 | pub struct Fuse<Fut> { |
| 492 | #[pin] |
| 493 | inner: Option<Fut>, |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | impl<Fut> Fuse<Fut> { |
| 498 | fn new(f: Fut) -> Self { |
| 499 | Self { inner: Some(f) } |
| 500 | } |
| 501 | } |
| 502 | |
| 503 | impl<Fut: Future> Future for Fuse<Fut> { |
| 504 | type Output = Fut::Output; |
| 505 | |
| 506 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Fut::Output> { |
| 507 | match self |
| 508 | .as_mut() |
| 509 | .project() |
| 510 | .inner |
| 511 | .as_pin_mut() |
| 512 | .map(|f: Pin<&mut Fut>| f.poll(cx)) |
| 513 | { |
| 514 | Some(Poll::Ready(output: ::Output)) => { |
| 515 | self.project().inner.set(None); |
| 516 | Poll::Ready(output) |
| 517 | } |
| 518 | |
| 519 | Some(Poll::Pending) | None => Poll::Pending, |
| 520 | } |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | /// Returns the result of the future that completes first, with no preference if both are ready. |
| 525 | /// |
| 526 | /// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore, no |
| 527 | /// future takes precedence over the other if both can complete at the same time. |
| 528 | /// |
| 529 | /// If you have preference for one of the futures, use the [`or()`] function or the |
| 530 | /// [`FutureExt::or()`] method. |
| 531 | /// |
| 532 | /// # Examples |
| 533 | /// |
| 534 | /// ``` |
| 535 | /// use futures_lite::future::{self, pending, ready}; |
| 536 | /// |
| 537 | /// # spin_on::spin_on(async { |
| 538 | /// assert_eq!(future::race(ready(1), pending()).await, 1); |
| 539 | /// assert_eq!(future::race(pending(), ready(2)).await, 2); |
| 540 | /// |
| 541 | /// // One of the two futures is randomly chosen as the winner. |
| 542 | /// let res = future::race(ready(1), ready(2)).await; |
| 543 | /// # }) |
| 544 | /// ``` |
| 545 | #[cfg (all(feature = "race" , feature = "std" ))] |
| 546 | pub fn race<T, F1, F2>(future1: F1, future2: F2) -> Race<F1, F2> |
| 547 | where |
| 548 | F1: Future<Output = T>, |
| 549 | F2: Future<Output = T>, |
| 550 | { |
| 551 | Race { |
| 552 | future1, |
| 553 | future2, |
| 554 | rng: Rng::new(), |
| 555 | } |
| 556 | } |
| 557 | |
| 558 | /// Race two futures but with a predefined random seed. |
| 559 | /// |
| 560 | /// This function is identical to [`race`], but instead of using a random seed from a thread-local |
| 561 | /// RNG, it allows the user to provide a seed. It is useful for when you already have a source of |
| 562 | /// randomness available, or if you want to use a fixed seed. |
| 563 | /// |
| 564 | /// See documentation of the [`race`] function for features and caveats. |
| 565 | /// |
| 566 | /// # Examples |
| 567 | /// |
| 568 | /// ``` |
| 569 | /// use futures_lite::future::{self, pending, ready}; |
| 570 | /// |
| 571 | /// // A fixed seed is used, so the result is deterministic. |
| 572 | /// const SEED: u64 = 0x42; |
| 573 | /// |
| 574 | /// # spin_on::spin_on(async { |
| 575 | /// assert_eq!(future::race_with_seed(ready(1), pending(), SEED).await, 1); |
| 576 | /// assert_eq!(future::race_with_seed(pending(), ready(2), SEED).await, 2); |
| 577 | /// |
| 578 | /// // One of the two futures is randomly chosen as the winner. |
| 579 | /// let res = future::race_with_seed(ready(1), ready(2), SEED).await; |
| 580 | /// # }) |
| 581 | /// ``` |
| 582 | #[cfg (feature = "race" )] |
| 583 | pub fn race_with_seed<T, F1, F2>(future1: F1, future2: F2, seed: u64) -> Race<F1, F2> |
| 584 | where |
| 585 | F1: Future<Output = T>, |
| 586 | F2: Future<Output = T>, |
| 587 | { |
| 588 | Race { |
| 589 | future1, |
| 590 | future2, |
| 591 | rng: Rng::with_seed(seed), |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | #[cfg (feature = "race" )] |
| 596 | pin_project! { |
| 597 | /// Future for the [`race()`] function and the [`FutureExt::race()`] method. |
| 598 | #[derive (Debug)] |
| 599 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
| 600 | pub struct Race<F1, F2> { |
| 601 | #[pin] |
| 602 | future1: F1, |
| 603 | #[pin] |
| 604 | future2: F2, |
| 605 | rng: Rng, |
| 606 | } |
| 607 | } |
| 608 | |
| 609 | #[cfg (feature = "race" )] |
| 610 | impl<T, F1, F2> Future for Race<F1, F2> |
| 611 | where |
| 612 | F1: Future<Output = T>, |
| 613 | F2: Future<Output = T>, |
| 614 | { |
| 615 | type Output = T; |
| 616 | |
| 617 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 618 | let this: Projection<'_, F1, F2> = self.project(); |
| 619 | |
| 620 | if this.rng.bool() { |
| 621 | if let Poll::Ready(t: T) = this.future1.poll(cx) { |
| 622 | return Poll::Ready(t); |
| 623 | } |
| 624 | if let Poll::Ready(t: T) = this.future2.poll(cx) { |
| 625 | return Poll::Ready(t); |
| 626 | } |
| 627 | } else { |
| 628 | if let Poll::Ready(t: T) = this.future2.poll(cx) { |
| 629 | return Poll::Ready(t); |
| 630 | } |
| 631 | if let Poll::Ready(t: T) = this.future1.poll(cx) { |
| 632 | return Poll::Ready(t); |
| 633 | } |
| 634 | } |
| 635 | Poll::Pending |
| 636 | } |
| 637 | } |
| 638 | |
| 639 | #[cfg (feature = "std" )] |
| 640 | pin_project! { |
| 641 | /// Future for the [`FutureExt::catch_unwind()`] method. |
| 642 | #[derive (Debug)] |
| 643 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
| 644 | pub struct CatchUnwind<F> { |
| 645 | #[pin] |
| 646 | inner: F, |
| 647 | } |
| 648 | } |
| 649 | |
| 650 | #[cfg (feature = "std" )] |
| 651 | impl<F: Future + UnwindSafe> Future for CatchUnwind<F> { |
| 652 | type Output = Result<F::Output, Box<dyn Any + Send>>; |
| 653 | |
| 654 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 655 | let this: Projection<'_, F> = self.project(); |
| 656 | catch_unwind(AssertUnwindSafe(|| this.inner.poll(cx)))?.map(Ok) |
| 657 | } |
| 658 | } |
| 659 | |
| 660 | /// Type alias for `Pin<Box<dyn Future<Output = T> + Send + 'static>>`. |
| 661 | /// |
| 662 | /// # Examples |
| 663 | /// |
| 664 | /// ``` |
| 665 | /// use futures_lite::future::{self, FutureExt}; |
| 666 | /// |
| 667 | /// // These two lines are equivalent: |
| 668 | /// let f1: future::Boxed<i32> = async { 1 + 2 }.boxed(); |
| 669 | /// let f2: future::Boxed<i32> = Box::pin(async { 1 + 2 }); |
| 670 | /// ``` |
| 671 | #[cfg (feature = "alloc" )] |
| 672 | pub type Boxed<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>; |
| 673 | |
| 674 | /// Type alias for `Pin<Box<dyn Future<Output = T> + 'static>>`. |
| 675 | /// |
| 676 | /// # Examples |
| 677 | /// |
| 678 | /// ``` |
| 679 | /// use futures_lite::future::{self, FutureExt}; |
| 680 | /// |
| 681 | /// // These two lines are equivalent: |
| 682 | /// let f1: future::BoxedLocal<i32> = async { 1 + 2 }.boxed_local(); |
| 683 | /// let f2: future::BoxedLocal<i32> = Box::pin(async { 1 + 2 }); |
| 684 | /// ``` |
| 685 | #[cfg (feature = "alloc" )] |
| 686 | pub type BoxedLocal<T> = Pin<Box<dyn Future<Output = T> + 'static>>; |
| 687 | |
| 688 | /// Extension trait for [`Future`]. |
| 689 | pub trait FutureExt: Future { |
| 690 | /// A convenience for calling [`Future::poll()`] on `!`[`Unpin`] types. |
| 691 | fn poll(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output> |
| 692 | where |
| 693 | Self: Unpin, |
| 694 | { |
| 695 | Future::poll(Pin::new(self), cx) |
| 696 | } |
| 697 | |
| 698 | /// Returns the result of `self` or `other` future, preferring `self` if both are ready. |
| 699 | /// |
| 700 | /// If you need to treat the two futures fairly without a preference for either, use the |
| 701 | /// [`race()`] function or the [`FutureExt::race()`] method. |
| 702 | /// |
| 703 | /// # Examples |
| 704 | /// |
| 705 | /// ``` |
| 706 | /// use futures_lite::future::{pending, ready, FutureExt}; |
| 707 | /// |
| 708 | /// # spin_on::spin_on(async { |
| 709 | /// assert_eq!(ready(1).or(pending()).await, 1); |
| 710 | /// assert_eq!(pending().or(ready(2)).await, 2); |
| 711 | /// |
| 712 | /// // The first future wins. |
| 713 | /// assert_eq!(ready(1).or(ready(2)).await, 1); |
| 714 | /// # }) |
| 715 | /// ``` |
| 716 | fn or<F>(self, other: F) -> Or<Self, F> |
| 717 | where |
| 718 | Self: Sized, |
| 719 | F: Future<Output = Self::Output>, |
| 720 | { |
| 721 | Or { |
| 722 | future1: self, |
| 723 | future2: other, |
| 724 | } |
| 725 | } |
| 726 | |
| 727 | /// Returns the result of `self` or `other` future, with no preference if both are ready. |
| 728 | /// |
| 729 | /// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore, |
| 730 | /// no future takes precedence over the other if both can complete at the same time. |
| 731 | /// |
| 732 | /// If you have preference for one of the futures, use the [`or()`] function or the |
| 733 | /// [`FutureExt::or()`] method. |
| 734 | /// |
| 735 | /// # Examples |
| 736 | /// |
| 737 | /// ``` |
| 738 | /// use futures_lite::future::{pending, ready, FutureExt}; |
| 739 | /// |
| 740 | /// # spin_on::spin_on(async { |
| 741 | /// assert_eq!(ready(1).race(pending()).await, 1); |
| 742 | /// assert_eq!(pending().race(ready(2)).await, 2); |
| 743 | /// |
| 744 | /// // One of the two futures is randomly chosen as the winner. |
| 745 | /// let res = ready(1).race(ready(2)).await; |
| 746 | /// # }) |
| 747 | /// ``` |
| 748 | #[cfg (all(feature = "std" , feature = "race" ))] |
| 749 | fn race<F>(self, other: F) -> Race<Self, F> |
| 750 | where |
| 751 | Self: Sized, |
| 752 | F: Future<Output = Self::Output>, |
| 753 | { |
| 754 | Race { |
| 755 | future1: self, |
| 756 | future2: other, |
| 757 | rng: Rng::new(), |
| 758 | } |
| 759 | } |
| 760 | |
| 761 | /// Catches panics while polling the future. |
| 762 | /// |
| 763 | /// # Examples |
| 764 | /// |
| 765 | /// ``` |
| 766 | /// use futures_lite::future::FutureExt; |
| 767 | /// |
| 768 | /// # spin_on::spin_on(async { |
| 769 | /// let fut1 = async {}.catch_unwind(); |
| 770 | /// let fut2 = async { panic!() }.catch_unwind(); |
| 771 | /// |
| 772 | /// assert!(fut1.await.is_ok()); |
| 773 | /// assert!(fut2.await.is_err()); |
| 774 | /// # }) |
| 775 | /// ``` |
| 776 | #[cfg (feature = "std" )] |
| 777 | fn catch_unwind(self) -> CatchUnwind<Self> |
| 778 | where |
| 779 | Self: Sized + UnwindSafe, |
| 780 | { |
| 781 | CatchUnwind { inner: self } |
| 782 | } |
| 783 | |
| 784 | /// Boxes the future and changes its type to `dyn Future + Send + 'a`. |
| 785 | /// |
| 786 | /// # Examples |
| 787 | /// |
| 788 | /// ``` |
| 789 | /// use futures_lite::future::{self, FutureExt}; |
| 790 | /// |
| 791 | /// # spin_on::spin_on(async { |
| 792 | /// let a = future::ready('a' ); |
| 793 | /// let b = future::pending(); |
| 794 | /// |
| 795 | /// // Futures of different types can be stored in |
| 796 | /// // the same collection when they are boxed: |
| 797 | /// let futures = vec![a.boxed(), b.boxed()]; |
| 798 | /// # }) |
| 799 | /// ``` |
| 800 | #[cfg (feature = "alloc" )] |
| 801 | fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>> |
| 802 | where |
| 803 | Self: Sized + Send + 'a, |
| 804 | { |
| 805 | Box::pin(self) |
| 806 | } |
| 807 | |
| 808 | /// Boxes the future and changes its type to `dyn Future + 'a`. |
| 809 | /// |
| 810 | /// # Examples |
| 811 | /// |
| 812 | /// ``` |
| 813 | /// use futures_lite::future::{self, FutureExt}; |
| 814 | /// |
| 815 | /// # spin_on::spin_on(async { |
| 816 | /// let a = future::ready('a' ); |
| 817 | /// let b = future::pending(); |
| 818 | /// |
| 819 | /// // Futures of different types can be stored in |
| 820 | /// // the same collection when they are boxed: |
| 821 | /// let futures = vec![a.boxed_local(), b.boxed_local()]; |
| 822 | /// # }) |
| 823 | /// ``` |
| 824 | #[cfg (feature = "alloc" )] |
| 825 | fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>> |
| 826 | where |
| 827 | Self: Sized + 'a, |
| 828 | { |
| 829 | Box::pin(self) |
| 830 | } |
| 831 | } |
| 832 | |
| 833 | impl<F: Future + ?Sized> FutureExt for F {} |
| 834 | |