diff --git a/src/future/mod.rs b/src/future/mod.rs index 29e2b047f..09474faa7 100644 --- a/src/future/mod.rs +++ b/src/future/mod.rs @@ -4,7 +4,9 @@ pub use std::future::Future; pub use pending::pending; +pub use poll_fn::poll_fn; pub use ready::ready; mod pending; +mod poll_fn; mod ready; diff --git a/src/future/poll_fn.rs b/src/future/poll_fn.rs new file mode 100644 index 000000000..f2e110dca --- /dev/null +++ b/src/future/poll_fn.rs @@ -0,0 +1,50 @@ +//! Definition of the `PollFn` adapter combinator + +use core::pin::Pin; +use std::future::Future; +use std::task::{Context, Poll}; + +/// Future for the [`poll_fn`] function. +#[must_use = "futures do nothing unless you `.await` or poll them"] +struct PollFn { + f: F, +} + +impl Unpin for PollFn {} + +/// Creates a new future wrapping around a function returning `Poll`. +/// +/// Polling the returned future delegates to the wrapped function. +/// +/// # Examples +/// +/// ``` +/// # fn main() { async_std::task::block_on(async { +/// # +/// use async_std::future::poll_fn; +/// use async_std::task::{Context, Poll}; +/// +/// fn read_line(_cx: &mut Context<'_>) -> Poll { +/// Poll::Ready("Hello, World!".into()) +/// } +/// +/// let read_future = poll_fn(read_line); +/// assert_eq!(read_future.await, "Hello, World!"); +/// # +/// # }) } +/// ``` +pub async fn poll_fn(f: impl FnMut(&mut Context<'_>) -> Poll) -> T { + let fut = PollFn { f }; + fut.await +} + +impl Future for PollFn +where + F: FnMut(&mut Context<'_>) -> Poll, +{ + type Output = T; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + (&mut self.f)(cx) + } +}