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