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}