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