core/task/poll.rs
1#![stable(feature = "futures_api", since = "1.36.0")]
2
3use crate::convert;
4use crate::ops::{self, ControlFlow};
5
6/// Indicates whether a value is available or if the current task has been
7/// scheduled to receive a wakeup instead.
8///
9/// This is returned by [`Future::poll`](core::future::Future::poll).
10#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"]
11#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
12#[lang = "Poll"]
13#[stable(feature = "futures_api", since = "1.36.0")]
14pub enum Poll<T> {
15 /// Represents that a value is immediately ready.
16 #[lang = "Ready"]
17 #[stable(feature = "futures_api", since = "1.36.0")]
18 Ready(#[stable(feature = "futures_api", since = "1.36.0")] T),
19
20 /// Represents that a value is not ready yet.
21 ///
22 /// When a function returns `Pending`, the function *must* also
23 /// ensure that the current task is scheduled to be awoken when
24 /// progress can be made.
25 #[lang = "Pending"]
26 #[stable(feature = "futures_api", since = "1.36.0")]
27 Pending,
28}
29
30impl<T> Poll<T> {
31 /// Maps a `Poll<T>` to `Poll<U>` by applying a function to a contained value.
32 ///
33 /// # Examples
34 ///
35 /// Converts a <code>Poll<[String]></code> into a <code>Poll<[usize]></code>, consuming
36 /// the original:
37 ///
38 /// [String]: ../../std/string/struct.String.html "String"
39 /// ```
40 /// # use core::task::Poll;
41 /// let poll_some_string = Poll::Ready(String::from("Hello, World!"));
42 /// // `Poll::map` takes self *by value*, consuming `poll_some_string`
43 /// let poll_some_len = poll_some_string.map(|s| s.len());
44 ///
45 /// assert_eq!(poll_some_len, Poll::Ready(13));
46 /// ```
47 #[stable(feature = "futures_api", since = "1.36.0")]
48 #[inline]
49 pub fn map<U, F>(self, f: F) -> Poll<U>
50 where
51 F: FnOnce(T) -> U,
52 {
53 match self {
54 Poll::Ready(t) => Poll::Ready(f(t)),
55 Poll::Pending => Poll::Pending,
56 }
57 }
58
59 /// Returns `true` if the poll is a [`Poll::Ready`] value.
60 ///
61 /// # Examples
62 ///
63 /// ```
64 /// # use core::task::Poll;
65 /// let x: Poll<u32> = Poll::Ready(2);
66 /// assert_eq!(x.is_ready(), true);
67 ///
68 /// let x: Poll<u32> = Poll::Pending;
69 /// assert_eq!(x.is_ready(), false);
70 /// ```
71 #[inline]
72 #[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
73 #[stable(feature = "futures_api", since = "1.36.0")]
74 pub const fn is_ready(&self) -> bool {
75 matches!(*self, Poll::Ready(_))
76 }
77
78 /// Returns `true` if the poll is a [`Pending`] value.
79 ///
80 /// [`Pending`]: Poll::Pending
81 ///
82 /// # Examples
83 ///
84 /// ```
85 /// # use core::task::Poll;
86 /// let x: Poll<u32> = Poll::Ready(2);
87 /// assert_eq!(x.is_pending(), false);
88 ///
89 /// let x: Poll<u32> = Poll::Pending;
90 /// assert_eq!(x.is_pending(), true);
91 /// ```
92 #[inline]
93 #[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
94 #[stable(feature = "futures_api", since = "1.36.0")]
95 pub const fn is_pending(&self) -> bool {
96 !self.is_ready()
97 }
98}
99
100impl<T, E> Poll<Result<T, E>> {
101 /// Maps a `Poll<Result<T, E>>` to `Poll<Result<U, E>>` by applying a
102 /// function to a contained `Poll::Ready(Ok)` value, leaving all other
103 /// variants untouched.
104 ///
105 /// This function can be used to compose the results of two functions.
106 ///
107 /// # Examples
108 ///
109 /// ```
110 /// # use core::task::Poll;
111 /// let res: Poll<Result<u8, _>> = Poll::Ready("12".parse());
112 /// let squared = res.map_ok(|n| n * n);
113 /// assert_eq!(squared, Poll::Ready(Ok(144)));
114 /// ```
115 #[stable(feature = "futures_api", since = "1.36.0")]
116 #[inline]
117 pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
118 where
119 F: FnOnce(T) -> U,
120 {
121 match self {
122 Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
123 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
124 Poll::Pending => Poll::Pending,
125 }
126 }
127
128 /// Maps a `Poll::Ready<Result<T, E>>` to `Poll::Ready<Result<T, F>>` by
129 /// applying a function to a contained `Poll::Ready(Err)` value, leaving all other
130 /// variants untouched.
131 ///
132 /// This function can be used to pass through a successful result while handling
133 /// an error.
134 ///
135 /// # Examples
136 ///
137 /// ```
138 /// # use core::task::Poll;
139 /// let res: Poll<Result<u8, _>> = Poll::Ready("oops".parse());
140 /// let res = res.map_err(|_| 0_u8);
141 /// assert_eq!(res, Poll::Ready(Err(0)));
142 /// ```
143 #[stable(feature = "futures_api", since = "1.36.0")]
144 #[inline]
145 pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
146 where
147 F: FnOnce(E) -> U,
148 {
149 match self {
150 Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
151 Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
152 Poll::Pending => Poll::Pending,
153 }
154 }
155}
156
157impl<T, E> Poll<Option<Result<T, E>>> {
158 /// Maps a `Poll<Option<Result<T, E>>>` to `Poll<Option<Result<U, E>>>` by
159 /// applying a function to a contained `Poll::Ready(Some(Ok))` value,
160 /// leaving all other variants untouched.
161 ///
162 /// This function can be used to compose the results of two functions.
163 ///
164 /// # Examples
165 ///
166 /// ```
167 /// # use core::task::Poll;
168 /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("12".parse()));
169 /// let squared = res.map_ok(|n| n * n);
170 /// assert_eq!(squared, Poll::Ready(Some(Ok(144))));
171 /// ```
172 #[stable(feature = "poll_map", since = "1.51.0")]
173 #[inline]
174 pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
175 where
176 F: FnOnce(T) -> U,
177 {
178 match self {
179 Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
180 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
181 Poll::Ready(None) => Poll::Ready(None),
182 Poll::Pending => Poll::Pending,
183 }
184 }
185
186 /// Maps a `Poll::Ready<Option<Result<T, E>>>` to
187 /// `Poll::Ready<Option<Result<T, F>>>` by applying a function to a
188 /// contained `Poll::Ready(Some(Err))` value, leaving all other variants
189 /// untouched.
190 ///
191 /// This function can be used to pass through a successful result while handling
192 /// an error.
193 ///
194 /// # Examples
195 ///
196 /// ```
197 /// # use core::task::Poll;
198 /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("oops".parse()));
199 /// let res = res.map_err(|_| 0_u8);
200 /// assert_eq!(res, Poll::Ready(Some(Err(0))));
201 /// ```
202 #[stable(feature = "poll_map", since = "1.51.0")]
203 #[inline]
204 pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
205 where
206 F: FnOnce(E) -> U,
207 {
208 match self {
209 Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
210 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))),
211 Poll::Ready(None) => Poll::Ready(None),
212 Poll::Pending => Poll::Pending,
213 }
214 }
215}
216
217#[stable(feature = "futures_api", since = "1.36.0")]
218impl<T> From<T> for Poll<T> {
219 /// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`.
220 ///
221 /// # Example
222 ///
223 /// ```
224 /// # use core::task::Poll;
225 /// assert_eq!(Poll::from(true), Poll::Ready(true));
226 /// ```
227 fn from(t: T) -> Poll<T> {
228 Poll::Ready(t)
229 }
230}
231
232#[unstable(feature = "try_trait_v2", issue = "84277")]
233impl<T, E> ops::Try for Poll<Result<T, E>> {
234 type Output = Poll<T>;
235 type Residual = Result<convert::Infallible, E>;
236
237 #[inline]
238 fn from_output(c: Self::Output) -> Self {
239 c.map(Ok)
240 }
241
242 #[inline]
243 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
244 match self {
245 Poll::Ready(Ok(x)) => ControlFlow::Continue(Poll::Ready(x)),
246 Poll::Ready(Err(e)) => ControlFlow::Break(Err(e)),
247 Poll::Pending => ControlFlow::Continue(Poll::Pending),
248 }
249 }
250}
251
252#[unstable(feature = "try_trait_v2", issue = "84277")]
253impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Poll<Result<T, F>> {
254 #[inline]
255 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
256 match x {
257 Err(e) => Poll::Ready(Err(From::from(e))),
258 }
259 }
260}
261
262#[unstable(feature = "try_trait_v2", issue = "84277")]
263impl<T, E> ops::Try for Poll<Option<Result<T, E>>> {
264 type Output = Poll<Option<T>>;
265 type Residual = Result<convert::Infallible, E>;
266
267 #[inline]
268 fn from_output(c: Self::Output) -> Self {
269 c.map(|x| x.map(Ok))
270 }
271
272 #[inline]
273 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
274 match self {
275 Poll::Ready(Some(Ok(x))) => ControlFlow::Continue(Poll::Ready(Some(x))),
276 Poll::Ready(Some(Err(e))) => ControlFlow::Break(Err(e)),
277 Poll::Ready(None) => ControlFlow::Continue(Poll::Ready(None)),
278 Poll::Pending => ControlFlow::Continue(Poll::Pending),
279 }
280 }
281}
282
283#[unstable(feature = "try_trait_v2", issue = "84277")]
284impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>>
285 for Poll<Option<Result<T, F>>>
286{
287 #[inline]
288 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
289 match x {
290 Err(e) => Poll::Ready(Some(Err(From::from(e)))),
291 }
292 }
293}