]> git.lizzy.rs Git - rust.git/blob - library/core/src/task/ready.rs
Rollup merge of #106414 - cuviper:libs-review, r=Mark-Simulacrum
[rust.git] / library / core / src / task / ready.rs
1 use core::convert;
2 use core::fmt;
3 use core::ops::{ControlFlow, FromResidual, Try};
4 use core::task::Poll;
5
6 /// Extracts the successful type of a [`Poll<T>`].
7 ///
8 /// This macro bakes in propagation of [`Pending`] signals by returning early.
9 ///
10 /// [`Poll<T>`]: crate::task::Poll
11 /// [`Pending`]: crate::task::Poll::Pending
12 ///
13 /// # Examples
14 ///
15 /// ```
16 /// use std::task::{ready, Context, Poll};
17 /// use std::future::{self, Future};
18 /// use std::pin::Pin;
19 ///
20 /// pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
21 ///     let mut fut = future::ready(42);
22 ///     let fut = Pin::new(&mut fut);
23 ///
24 ///     let num = ready!(fut.poll(cx));
25 ///     # drop(num);
26 ///     // ... use num
27 ///
28 ///     Poll::Ready(())
29 /// }
30 /// ```
31 ///
32 /// The `ready!` call expands to:
33 ///
34 /// ```
35 /// # use std::task::{Context, Poll};
36 /// # use std::future::{self, Future};
37 /// # use std::pin::Pin;
38 /// #
39 /// # pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
40 ///     # let mut fut = future::ready(42);
41 ///     # let fut = Pin::new(&mut fut);
42 ///     #
43 /// let num = match fut.poll(cx) {
44 ///     Poll::Ready(t) => t,
45 ///     Poll::Pending => return Poll::Pending,
46 /// };
47 ///     # drop(num);
48 ///     # // ... use num
49 ///     #
50 ///     # Poll::Ready(())
51 /// # }
52 /// ```
53 #[stable(feature = "ready_macro", since = "1.64.0")]
54 #[rustc_macro_transparency = "semitransparent"]
55 pub macro ready($e:expr) {
56     match $e {
57         $crate::task::Poll::Ready(t) => t,
58         $crate::task::Poll::Pending => {
59             return $crate::task::Poll::Pending;
60         }
61     }
62 }
63
64 /// Extracts the successful type of a [`Poll<T>`].
65 ///
66 /// See [`Poll::ready`] for details.
67 #[unstable(feature = "poll_ready", issue = "89780")]
68 pub struct Ready<T>(pub(crate) Poll<T>);
69
70 #[unstable(feature = "poll_ready", issue = "89780")]
71 impl<T> Try for Ready<T> {
72     type Output = T;
73     type Residual = Ready<convert::Infallible>;
74
75     #[inline]
76     fn from_output(output: Self::Output) -> Self {
77         Ready(Poll::Ready(output))
78     }
79
80     #[inline]
81     fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
82         match self.0 {
83             Poll::Ready(v) => ControlFlow::Continue(v),
84             Poll::Pending => ControlFlow::Break(Ready(Poll::Pending)),
85         }
86     }
87 }
88
89 #[unstable(feature = "poll_ready", issue = "89780")]
90 impl<T> FromResidual for Ready<T> {
91     #[inline]
92     fn from_residual(residual: Ready<convert::Infallible>) -> Self {
93         match residual.0 {
94             Poll::Pending => Ready(Poll::Pending),
95         }
96     }
97 }
98
99 #[unstable(feature = "poll_ready", issue = "89780")]
100 impl<T> FromResidual<Ready<convert::Infallible>> for Poll<T> {
101     #[inline]
102     fn from_residual(residual: Ready<convert::Infallible>) -> Self {
103         match residual.0 {
104             Poll::Pending => Poll::Pending,
105         }
106     }
107 }
108
109 #[unstable(feature = "poll_ready", issue = "89780")]
110 impl<T> fmt::Debug for Ready<T> {
111     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112         f.debug_tuple("Ready").finish()
113     }
114 }