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#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"]
9#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
10#[lang = "Poll"]
11#[stable(feature = "futures_api", since = "1.36.0")]
12pub 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
28impl<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 <code>Poll<[String]></code> into a <code>Poll<[usize]></code>, consuming
34 /// the original:
35 ///
36 /// [String]: ../../std/string/struct.String.html "String"
37 /// ```
38 /// # use core::task::Poll;
39 /// let poll_some_string = Poll::Ready(String::from("Hello, World!"));
40 /// // `Poll::map` takes self *by value*, consuming `poll_some_string`
41 /// let poll_some_len = poll_some_string.map(|s| s.len());
42 ///
43 /// assert_eq!(poll_some_len, Poll::Ready(13));
44 /// ```
45 #[stable(feature = "futures_api", since = "1.36.0")]
46 #[inline]
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
98impl<T, E> Poll<Result<T, E>> {
99 /// Maps a `Poll<Result<T, E>>` to `Poll<Result<U, E>>` by applying a
100 /// function to a contained `Poll::Ready(Ok)` value, leaving all other
101 /// variants untouched.
102 ///
103 /// This function can be used to compose the results of two functions.
104 ///
105 /// # Examples
106 ///
107 /// ```
108 /// # use core::task::Poll;
109 /// let res: Poll<Result<u8, _>> = Poll::Ready("12".parse());
110 /// let squared = res.map_ok(|n| n * n);
111 /// assert_eq!(squared, Poll::Ready(Ok(144)));
112 /// ```
113 #[stable(feature = "futures_api", since = "1.36.0")]
114 #[inline]
115 pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
116 where
117 F: FnOnce(T) -> U,
118 {
119 match self {
120 Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
121 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
122 Poll::Pending => Poll::Pending,
123 }
124 }
125
126 /// Maps a `Poll::Ready<Result<T, E>>` to `Poll::Ready<Result<T, F>>` by
127 /// applying a function to a contained `Poll::Ready(Err)` value, leaving all other
128 /// variants untouched.
129 ///
130 /// This function can be used to pass through a successful result while handling
131 /// an error.
132 ///
133 /// # Examples
134 ///
135 /// ```
136 /// # use core::task::Poll;
137 /// let res: Poll<Result<u8, _>> = Poll::Ready("oops".parse());
138 /// let res = res.map_err(|_| 0_u8);
139 /// assert_eq!(res, Poll::Ready(Err(0)));
140 /// ```
141 #[stable(feature = "futures_api", since = "1.36.0")]
142 #[inline]
143 pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
144 where
145 F: FnOnce(E) -> U,
146 {
147 match self {
148 Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
149 Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
150 Poll::Pending => Poll::Pending,
151 }
152 }
153}
154
155impl<T, E> Poll<Option<Result<T, E>>> {
156 /// Maps a `Poll<Option<Result<T, E>>>` to `Poll<Option<Result<U, E>>>` by
157 /// applying a function to a contained `Poll::Ready(Some(Ok))` value,
158 /// leaving all other variants untouched.
159 ///
160 /// This function can be used to compose the results of two functions.
161 ///
162 /// # Examples
163 ///
164 /// ```
165 /// # use core::task::Poll;
166 /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("12".parse()));
167 /// let squared = res.map_ok(|n| n * n);
168 /// assert_eq!(squared, Poll::Ready(Some(Ok(144))));
169 /// ```
170 #[stable(feature = "poll_map", since = "1.51.0")]
171 #[inline]
172 pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
173 where
174 F: FnOnce(T) -> U,
175 {
176 match self {
177 Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
178 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
179 Poll::Ready(None) => Poll::Ready(None),
180 Poll::Pending => Poll::Pending,
181 }
182 }
183
184 /// Maps a `Poll::Ready<Option<Result<T, E>>>` to
185 /// `Poll::Ready<Option<Result<T, F>>>` by applying a function to a
186 /// contained `Poll::Ready(Some(Err))` value, leaving all other variants
187 /// untouched.
188 ///
189 /// This function can be used to pass through a successful result while handling
190 /// an error.
191 ///
192 /// # Examples
193 ///
194 /// ```
195 /// # use core::task::Poll;
196 /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("oops".parse()));
197 /// let res = res.map_err(|_| 0_u8);
198 /// assert_eq!(res, Poll::Ready(Some(Err(0))));
199 /// ```
200 #[stable(feature = "poll_map", since = "1.51.0")]
201 #[inline]
202 pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
203 where
204 F: FnOnce(E) -> U,
205 {
206 match self {
207 Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
208 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))),
209 Poll::Ready(None) => Poll::Ready(None),
210 Poll::Pending => Poll::Pending,
211 }
212 }
213}
214
215#[stable(feature = "futures_api", since = "1.36.0")]
216impl<T> From<T> for Poll<T> {
217 /// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`.
218 ///
219 /// # Example
220 ///
221 /// ```
222 /// # use core::task::Poll;
223 /// assert_eq!(Poll::from(true), Poll::Ready(true));
224 /// ```
225 fn from(t: T) -> Poll<T> {
226 Poll::Ready(t)
227 }
228}
229
230#[unstable(feature = "try_trait_v2", issue = "84277")]
231impl<T, E> ops::Try for Poll<Result<T, E>> {
232 type Output = Poll<T>;
233 type Residual = Result<convert::Infallible, E>;
234
235 #[inline]
236 fn from_output(c: Self::Output) -> Self {
237 c.map(Ok)
238 }
239
240 #[inline]
241 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
242 match self {
243 Poll::Ready(Ok(x: T)) => ControlFlow::Continue(Poll::Ready(x)),
244 Poll::Ready(Err(e: E)) => ControlFlow::Break(Err(e)),
245 Poll::Pending => ControlFlow::Continue(Poll::Pending),
246 }
247 }
248}
249
250#[unstable(feature = "try_trait_v2", issue = "84277")]
251impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Poll<Result<T, F>> {
252 #[inline]
253 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
254 match x {
255 Err(e: E) => Poll::Ready(Err(From::from(e))),
256 }
257 }
258}
259
260#[unstable(feature = "try_trait_v2", issue = "84277")]
261impl<T, E> ops::Try for Poll<Option<Result<T, E>>> {
262 type Output = Poll<Option<T>>;
263 type Residual = Result<convert::Infallible, E>;
264
265 #[inline]
266 fn from_output(c: Self::Output) -> Self {
267 c.map(|x: Option| x.map(Ok))
268 }
269
270 #[inline]
271 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
272 match self {
273 Poll::Ready(Some(Ok(x: T))) => ControlFlow::Continue(Poll::Ready(Some(x))),
274 Poll::Ready(Some(Err(e: E))) => ControlFlow::Break(Err(e)),
275 Poll::Ready(None) => ControlFlow::Continue(Poll::Ready(None)),
276 Poll::Pending => ControlFlow::Continue(Poll::Pending),
277 }
278 }
279}
280
281#[unstable(feature = "try_trait_v2", issue = "84277")]
282impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>>
283 for Poll<Option<Result<T, F>>>
284{
285 #[inline]
286 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
287 match x {
288 Err(e: E) => Poll::Ready(Some(Err(From::from(e)))),
289 }
290 }
291}
292