]> git.lizzy.rs Git - rust.git/blob - library/core/src/task/poll.rs
Rollup merge of #102037 - jyn514:normalize-docs, r=lcnr
[rust.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 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
245 impl<T> const From<T> for Poll<T> {
246     /// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`.
247     ///
248     /// # Example
249     ///
250     /// ```
251     /// # use core::task::Poll;
252     /// assert_eq!(Poll::from(true), Poll::Ready(true));
253     /// ```
254     fn from(t: T) -> Poll<T> {
255         Poll::Ready(t)
256     }
257 }
258
259 #[unstable(feature = "try_trait_v2", issue = "84277")]
260 impl<T, E> ops::Try for Poll<Result<T, E>> {
261     type Output = Poll<T>;
262     type Residual = Result<convert::Infallible, E>;
263
264     #[inline]
265     fn from_output(c: Self::Output) -> Self {
266         c.map(Ok)
267     }
268
269     #[inline]
270     fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
271         match self {
272             Poll::Ready(Ok(x)) => ControlFlow::Continue(Poll::Ready(x)),
273             Poll::Ready(Err(e)) => ControlFlow::Break(Err(e)),
274             Poll::Pending => ControlFlow::Continue(Poll::Pending),
275         }
276     }
277 }
278
279 #[unstable(feature = "try_trait_v2", issue = "84277")]
280 impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Poll<Result<T, F>> {
281     #[inline]
282     fn from_residual(x: Result<convert::Infallible, E>) -> Self {
283         match x {
284             Err(e) => Poll::Ready(Err(From::from(e))),
285         }
286     }
287 }
288
289 #[unstable(feature = "try_trait_v2", issue = "84277")]
290 impl<T, E> ops::Try for Poll<Option<Result<T, E>>> {
291     type Output = Poll<Option<T>>;
292     type Residual = Result<convert::Infallible, E>;
293
294     #[inline]
295     fn from_output(c: Self::Output) -> Self {
296         c.map(|x| x.map(Ok))
297     }
298
299     #[inline]
300     fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
301         match self {
302             Poll::Ready(Some(Ok(x))) => ControlFlow::Continue(Poll::Ready(Some(x))),
303             Poll::Ready(Some(Err(e))) => ControlFlow::Break(Err(e)),
304             Poll::Ready(None) => ControlFlow::Continue(Poll::Ready(None)),
305             Poll::Pending => ControlFlow::Continue(Poll::Pending),
306         }
307     }
308 }
309
310 #[unstable(feature = "try_trait_v2", issue = "84277")]
311 impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>>
312     for Poll<Option<Result<T, F>>>
313 {
314     #[inline]
315     fn from_residual(x: Result<convert::Infallible, E>) -> Self {
316         match x {
317             Err(e) => Poll::Ready(Some(Err(From::from(e)))),
318         }
319     }
320 }