af_core/
future.rs

1// Copyright © 2020 Alexandra Frydl
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7//! Common [`Future`] types and utilities.
8
9pub use af_core_macros::{future_boxed as boxed, future_boxed_local as boxed_local};
10pub use std::future::Future;
11pub use std::task::{Context, Poll};
12
13mod noop_waker;
14mod try_future;
15
16pub use self::try_future::*;
17
18use crate::prelude::*;
19
20/// Waits for a future to be ready or panic.
21///
22/// If the future panics, this function returns an `Err` with the panic value.
23pub async fn catch_unwind<F>(f: F) -> Result<F::Output, Box<dyn Any + Send>>
24where
25  F: Future + panic::UnwindSafe,
26{
27  use futures_lite::FutureExt;
28
29  f.catch_unwind().await
30}
31
32/// Waits forever.
33pub async fn forever<T>() -> T {
34  futures_lite::future::pending().await
35}
36
37/// Polls a future and returns its result if it is ready.
38pub fn poll<F: Future + Unpin>(f: &mut F) -> Option<F::Output> {
39  match Pin::new(f).poll(&mut noop_waker::context()) {
40    Poll::Ready(value) => Some(value),
41    _ => None,
42  }
43}
44
45/// Waits for one of two futures to be ready and returns its result.
46///
47/// The remaining future is dropped. If both futures are ready at the same time,
48/// the first future has priority.
49pub async fn race<T>(a: impl Future<Output = T>, b: impl Future<Output = T>) -> T {
50  use futures_lite::FutureExt;
51
52  a.or(b).await
53}
54
55/// Polls the future once then drops it, returning the output if the future was
56/// ready.
57pub fn try_resolve<T>(f: impl Future<Output = T>) -> Option<T> {
58  pin!(f);
59  poll(&mut f)
60}