Skip to main content

core/task/
poll.rs

1#![stable(feature = "futures_api", since = "1.36.0")]
2
3use crate::ops::{self, ControlFlow};
4
5/// Indicates whether a value is available or if the current task has been
6/// scheduled to receive a wakeup instead.
7///
8/// This is returned by [`Future::poll`](core::future::Future::poll).
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#[lang = "Poll"]
12#[stable(feature = "futures_api", since = "1.36.0")]
13pub 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
29impl<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    #[inline]
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
99impl<T, E> Poll<Result<T, E>> {
100    /// Maps a `Poll<Result<T, E>>` to `Poll<Result<U, E>>` by applying a
101    /// function to a contained `Poll::Ready(Ok)` value, leaving all other
102    /// variants untouched.
103    ///
104    /// This function can be used to compose the results of two functions.
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// # use core::task::Poll;
110    /// let res: Poll<Result<u8, _>> = Poll::Ready("12".parse());
111    /// let squared = res.map_ok(|n| n * n);
112    /// assert_eq!(squared, Poll::Ready(Ok(144)));
113    /// ```
114    #[stable(feature = "futures_api", since = "1.36.0")]
115    #[inline]
116    pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
117    where
118        F: FnOnce(T) -> U,
119    {
120        match self {
121            Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
122            Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
123            Poll::Pending => Poll::Pending,
124        }
125    }
126
127    /// Maps a `Poll::Ready<Result<T, E>>` to `Poll::Ready<Result<T, U>>` by
128    /// applying a function to a contained `Poll::Ready(Err)` value, leaving all other
129    /// variants untouched.
130    ///
131    /// This function can be used to pass through a successful result while handling
132    /// an error.
133    ///
134    /// # Examples
135    ///
136    /// ```
137    /// # use core::task::Poll;
138    /// let res: Poll<Result<u8, _>> = Poll::Ready("oops".parse());
139    /// let res = res.map_err(|_| 0_u8);
140    /// assert_eq!(res, Poll::Ready(Err(0)));
141    /// ```
142    #[stable(feature = "futures_api", since = "1.36.0")]
143    #[inline]
144    pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
145    where
146        F: FnOnce(E) -> U,
147    {
148        match self {
149            Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
150            Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
151            Poll::Pending => Poll::Pending,
152        }
153    }
154}
155
156impl<T, E> Poll<Option<Result<T, E>>> {
157    /// Maps a `Poll<Option<Result<T, E>>>` to `Poll<Option<Result<U, E>>>` by
158    /// applying a function to a contained `Poll::Ready(Some(Ok))` value,
159    /// leaving all other variants untouched.
160    ///
161    /// This function can be used to compose the results of two functions.
162    ///
163    /// # Examples
164    ///
165    /// ```
166    /// # use core::task::Poll;
167    /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("12".parse()));
168    /// let squared = res.map_ok(|n| n * n);
169    /// assert_eq!(squared, Poll::Ready(Some(Ok(144))));
170    /// ```
171    #[stable(feature = "poll_map", since = "1.51.0")]
172    #[inline]
173    pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
174    where
175        F: FnOnce(T) -> U,
176    {
177        match self {
178            Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
179            Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
180            Poll::Ready(None) => Poll::Ready(None),
181            Poll::Pending => Poll::Pending,
182        }
183    }
184
185    /// Maps a `Poll::Ready<Option<Result<T, E>>>` to
186    /// `Poll::Ready<Option<Result<T, F>>>` by applying a function to a
187    /// contained `Poll::Ready(Some(Err))` value, leaving all other variants
188    /// untouched.
189    ///
190    /// This function can be used to pass through a successful result while handling
191    /// an error.
192    ///
193    /// # Examples
194    ///
195    /// ```
196    /// # use core::task::Poll;
197    /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("oops".parse()));
198    /// let res = res.map_err(|_| 0_u8);
199    /// assert_eq!(res, Poll::Ready(Some(Err(0))));
200    /// ```
201    #[stable(feature = "poll_map", since = "1.51.0")]
202    #[inline]
203    pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
204    where
205        F: FnOnce(E) -> U,
206    {
207        match self {
208            Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
209            Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))),
210            Poll::Ready(None) => Poll::Ready(None),
211            Poll::Pending => Poll::Pending,
212        }
213    }
214}
215
216#[stable(feature = "futures_api", since = "1.36.0")]
217#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
218const impl<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", old_name = "try_trait")]
233impl<T, E> ops::Try for Poll<Result<T, E>> {
234    type Output = Poll<T>;
235    type Residual = Result<!, 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", old_name = "try_trait")]
253impl<T, E, F: From<E>> ops::FromResidual<Result<!, E>> for Poll<Result<T, F>> {
254    #[inline]
255    fn from_residual(x: Result<!, 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", old_name = "try_trait")]
263impl<T, E> ops::Try for Poll<Option<Result<T, E>>> {
264    type Output = Poll<Option<T>>;
265    type Residual = Result<!, 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", old_name = "try_trait")]
284impl<T, E, F: From<E>> ops::FromResidual<Result<!, E>> for Poll<Option<Result<T, F>>> {
285    #[inline]
286    fn from_residual(x: Result<!, E>) -> Self {
287        match x {
288            Err(e) => Poll::Ready(Some(Err(From::from(e)))),
289        }
290    }
291}