]> git.proxmox.com Git - rustc.git/blob - library/core/src/task/poll.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.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 #[unstable(feature = "try_trait_v2", issue = "84277")]
225 impl<T, E> ops::Try for Poll<Result<T, E>> {
226 type Output = Poll<T>;
227 type Residual = Result<convert::Infallible, E>;
228
229 #[inline]
230 fn from_output(c: Self::Output) -> Self {
231 c.map(Ok)
232 }
233
234 #[inline]
235 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
236 match self {
237 Poll::Ready(Ok(x)) => ControlFlow::Continue(Poll::Ready(x)),
238 Poll::Ready(Err(e)) => ControlFlow::Break(Err(e)),
239 Poll::Pending => ControlFlow::Continue(Poll::Pending),
240 }
241 }
242 }
243
244 #[unstable(feature = "try_trait_v2", issue = "84277")]
245 impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Poll<Result<T, F>> {
246 #[inline]
247 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
248 match x {
249 Err(e) => Poll::Ready(Err(From::from(e))),
250 }
251 }
252 }
253
254 #[unstable(feature = "try_trait_v2", issue = "84277")]
255 impl<T, E> ops::Try for Poll<Option<Result<T, E>>> {
256 type Output = Poll<Option<T>>;
257 type Residual = Result<convert::Infallible, E>;
258
259 #[inline]
260 fn from_output(c: Self::Output) -> Self {
261 c.map(|x| x.map(Ok))
262 }
263
264 #[inline]
265 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
266 match self {
267 Poll::Ready(Some(Ok(x))) => ControlFlow::Continue(Poll::Ready(Some(x))),
268 Poll::Ready(Some(Err(e))) => ControlFlow::Break(Err(e)),
269 Poll::Ready(None) => ControlFlow::Continue(Poll::Ready(None)),
270 Poll::Pending => ControlFlow::Continue(Poll::Pending),
271 }
272 }
273 }
274
275 #[unstable(feature = "try_trait_v2", issue = "84277")]
276 impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>>
277 for Poll<Option<Result<T, F>>>
278 {
279 #[inline]
280 fn from_residual(x: Result<convert::Infallible, E>) -> Self {
281 match x {
282 Err(e) => Poll::Ready(Some(Err(From::from(e)))),
283 }
284 }
285 }