summaryrefslogtreecommitdiffstats
path: root/library/core/src/task/ready.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/core/src/task/ready.rs')
-rw-r--r--library/core/src/task/ready.rs114
1 files changed, 114 insertions, 0 deletions
diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs
new file mode 100644
index 000000000..b1daf545f
--- /dev/null
+++ b/library/core/src/task/ready.rs
@@ -0,0 +1,114 @@
+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.
+///
+/// [`Poll<T>`]: crate::task::Poll
+/// [`Pending`]: crate::task::Poll::Pending
+///
+/// # Examples
+///
+/// ```
+/// use std::task::{ready, 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 = ready!(fut.poll(cx));
+/// # drop(num);
+/// // ... use num
+///
+/// Poll::Ready(())
+/// }
+/// ```
+///
+/// The `ready!` call expands to:
+///
+/// ```
+/// # 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 = match fut.poll(cx) {
+/// Poll::Ready(t) => t,
+/// Poll::Pending => return Poll::Pending,
+/// };
+/// # drop(num);
+/// # // ... use num
+/// #
+/// # Poll::Ready(())
+/// # }
+/// ```
+#[stable(feature = "ready_macro", since = "1.64.0")]
+#[rustc_macro_transparency = "semitransparent"]
+pub macro ready($e:expr) {
+ match $e {
+ $crate::task::Poll::Ready(t) => t,
+ $crate::task::Poll::Pending => {
+ return $crate::task::Poll::Pending;
+ }
+ }
+}
+
+/// Extracts the successful type of a [`Poll<T>`].
+///
+/// See [`Poll::ready`] for details.
+#[unstable(feature = "poll_ready", issue = "89780")]
+pub struct Ready<T>(pub(crate) Poll<T>);
+
+#[unstable(feature = "poll_ready", issue = "89780")]
+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 = "89780")]
+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 = "89780")]
+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 = "89780")]
+impl<T> fmt::Debug for Ready<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("Ready").finish()
+ }
+}