diff options
| author | Ibraheem Ahmed <ibrah1440@gmail.com> | 2021-10-07 15:47:28 -0400 |
|---|---|---|
| committer | Ibraheem Ahmed <ibrah1440@gmail.com> | 2021-10-07 15:47:28 -0400 |
| commit | a57c18b5e182f32218ace2620163d86b9412182d (patch) | |
| tree | 974b96bf9a703bda1cb6a32ed9777f6217f49dce | |
| parent | 0157cc977fd71297ce73e2f249321f5ba2555d42 (diff) | |
| download | rust-a57c18b5e182f32218ace2620163d86b9412182d.tar.gz rust-a57c18b5e182f32218ace2620163d86b9412182d.zip | |
add `Poll::ready`
| -rw-r--r-- | library/core/src/task/mod.rs | 2 | ||||
| -rw-r--r-- | library/core/src/task/poll.rs | 33 | ||||
| -rw-r--r-- | library/core/src/task/ready.rs | 57 |
3 files changed, 92 insertions, 0 deletions
diff --git a/library/core/src/task/mod.rs b/library/core/src/task/mod.rs index 5f077f77bbc..a872320aca6 100644 --- a/library/core/src/task/mod.rs +++ b/library/core/src/task/mod.rs @@ -13,3 +13,5 @@ pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker}; mod ready; #[stable(feature = "ready_macro", since = "1.56.0")] pub use ready::ready; +#[unstable(feature = "poll_ready", issue = "none")] +pub use ready::Ready; diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 57416aeb701..924c424548f 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -3,6 +3,7 @@ use crate::convert; use crate::ops::{self, ControlFlow}; use crate::result::Result; +use crate::task::Ready; /// Indicates whether a value is available or if the current task has been /// scheduled to receive a wakeup instead. @@ -92,6 +93,38 @@ impl<T> Poll<T> { pub const fn is_pending(&self) -> bool { !self.is_ready() } + + /// Extracts the successful type of a [`Poll<T>`]. + /// + /// When combined with the `?` operator, this function will + /// propogate any [`Poll::Pending`] values to the caller, and + /// extract the `T` from [`Poll::Ready`]. + /// + /// # Examples + /// + /// ```rust + /// #![feature(poll_ready)] + /// + /// use std::task::{Context, Poll}; + /// use std::future::{self, Future}; + /// use std::pin::Pin; + /// + /// pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> { + /// let mut fut = future::ready(42); + /// let fut = Pin::new(&mut fut); + /// + /// let num = fut.poll(cx).ready()?; + /// # drop(num); + /// // ... use num + /// + /// Poll::Ready(()) + /// } + /// ``` + #[inline] + #[unstable(feature = "poll_ready", issue = "none")] + pub fn ready(self) -> Ready<T> { + Ready(self) + } } impl<T, E> Poll<Result<T, E>> { diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs index 2834ca5fe22..8b6e259134e 100644 --- a/library/core/src/task/ready.rs +++ b/library/core/src/task/ready.rs @@ -1,3 +1,8 @@ +use core::convert; +use core::fmt; +use core::ops::{ControlFlow, FromResidual, Try}; +use core::task::Poll; + /// Extracts the successful type of a [`Poll<T>`]. /// /// This macro bakes in propagation of [`Pending`] signals by returning early. @@ -55,3 +60,55 @@ pub macro ready($e:expr) { } } } + +/// Extracts the successful type of a [`Poll<T>`]. +/// +/// See [`Poll::ready`] for details. +#[unstable(feature = "poll_ready", issue = "none")] +pub struct Ready<T>(pub(crate) Poll<T>); + +#[unstable(feature = "poll_ready", issue = "none")] +impl<T> Try for Ready<T> { + type Output = T; + type Residual = Ready<convert::Infallible>; + + #[inline] + fn from_output(output: Self::Output) -> Self { + Ready(Poll::Ready(output)) + } + + #[inline] + fn branch(self) -> ControlFlow<Self::Residual, Self::Output> { + match self.0 { + Poll::Ready(v) => ControlFlow::Continue(v), + Poll::Pending => ControlFlow::Break(Ready(Poll::Pending)), + } + } +} + +#[unstable(feature = "poll_ready", issue = "none")] +impl<T> FromResidual for Ready<T> { + #[inline] + fn from_residual(residual: Ready<convert::Infallible>) -> Self { + match residual.0 { + Poll::Pending => Ready(Poll::Pending), + } + } +} + +#[unstable(feature = "poll_ready", issue = "none")] +impl<T> FromResidual<Ready<convert::Infallible>> for Poll<T> { + #[inline] + fn from_residual(residual: Ready<convert::Infallible>) -> Self { + match residual.0 { + Poll::Pending => Poll::Pending, + } + } +} + +#[unstable(feature = "poll_ready", issue = "none")] +impl<T> fmt::Debug for Ready<T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Ready").finish() + } +} |
