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