1 | cfg_unstable! { |
2 | mod delay; |
3 | mod flatten; |
4 | mod race; |
5 | mod try_race; |
6 | mod join; |
7 | mod try_join; |
8 | |
9 | use std::time::Duration; |
10 | use delay::DelayFuture; |
11 | use flatten::FlattenFuture; |
12 | use crate::future::IntoFuture; |
13 | use race::Race; |
14 | use try_race::TryRace; |
15 | use join::Join; |
16 | use try_join::TryJoin; |
17 | } |
18 | |
19 | cfg_unstable_default! { |
20 | use crate::future::timeout::TimeoutFuture; |
21 | } |
22 | |
23 | pub use core::future::Future as Future; |
24 | |
25 | #[doc = r#" |
26 | Extension methods for [`Future`]. |
27 | |
28 | [`Future`]: ../future/trait.Future.html |
29 | "# ] |
30 | #[cfg (any(feature = "std" , feature = "docs" ))] |
31 | pub trait FutureExt: Future { |
32 | /// Returns a Future that delays execution for a specified time. |
33 | /// |
34 | /// # Examples |
35 | /// |
36 | /// ``` |
37 | /// # async_std::task::block_on(async { |
38 | /// use async_std::prelude::*; |
39 | /// use async_std::future; |
40 | /// use std::time::Duration; |
41 | /// |
42 | /// let a = future::ready(1).delay(Duration::from_millis(2000)); |
43 | /// dbg!(a.await); |
44 | /// # }) |
45 | /// ``` |
46 | #[cfg (feature = "unstable" )] |
47 | #[cfg_attr (feature = "docs" , doc(cfg(unstable)))] |
48 | fn delay(self, dur: Duration) -> DelayFuture<Self> |
49 | where |
50 | Self: Sized, |
51 | { |
52 | DelayFuture::new(self, dur) |
53 | } |
54 | |
55 | /// Flatten out the execution of this future when the result itself |
56 | /// can be converted into another future. |
57 | /// |
58 | /// # Examples |
59 | /// |
60 | /// ``` |
61 | /// # async_std::task::block_on(async { |
62 | /// use async_std::prelude::*; |
63 | /// |
64 | /// let nested_future = async { async { 1 } }; |
65 | /// let future = nested_future.flatten(); |
66 | /// assert_eq!(future.await, 1); |
67 | /// # }) |
68 | /// ``` |
69 | #[cfg (feature = "unstable" )] |
70 | #[cfg_attr (feature = "docs" , doc(cfg(unstable)))] |
71 | fn flatten( |
72 | self, |
73 | ) -> FlattenFuture<Self, <Self::Output as IntoFuture>::Future> |
74 | where |
75 | Self: Sized, |
76 | <Self as Future>::Output: IntoFuture, |
77 | { |
78 | FlattenFuture::new(self) |
79 | } |
80 | |
81 | #[doc = r#" |
82 | Waits for one of two similarly-typed futures to complete. |
83 | |
84 | Awaits multiple futures simultaneously, returning the output of the |
85 | first future that completes. |
86 | |
87 | This function will return a new future which awaits for either one of both |
88 | futures to complete. If multiple futures are completed at the same time, |
89 | resolution will occur in the order that they have been passed. |
90 | |
91 | Note that this function consumes all futures passed, and once a future is |
92 | completed, all other futures are dropped. |
93 | |
94 | # Examples |
95 | |
96 | ``` |
97 | # async_std::task::block_on(async { |
98 | use async_std::prelude::*; |
99 | use async_std::future; |
100 | |
101 | let a = future::pending(); |
102 | let b = future::ready(1u8); |
103 | let c = future::ready(2u8); |
104 | |
105 | let f = a.race(b).race(c); |
106 | assert_eq!(f.await, 1u8); |
107 | # }); |
108 | ``` |
109 | "# ] |
110 | #[cfg (feature = "unstable" )] |
111 | #[cfg_attr (feature = "docs" , doc(cfg(unstable)))] |
112 | fn race<F>( |
113 | self, |
114 | other: F, |
115 | ) -> Race<Self, F> |
116 | where |
117 | Self: std::future::Future + Sized, |
118 | F: std::future::Future<Output = <Self as std::future::Future>::Output>, |
119 | { |
120 | Race::new(self, other) |
121 | } |
122 | |
123 | #[doc = r#" |
124 | Waits for one of two similarly-typed fallible futures to complete. |
125 | |
126 | Awaits multiple futures simultaneously, returning all results once complete. |
127 | |
128 | `try_race` is similar to [`race`], but keeps going if a future |
129 | resolved to an error until all futures have been resolved. In which case |
130 | an error is returned. |
131 | |
132 | The ordering of which value is yielded when two futures resolve |
133 | simultaneously is intentionally left unspecified. |
134 | |
135 | [`race`]: #method.race |
136 | |
137 | # Examples |
138 | |
139 | ``` |
140 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
141 | # |
142 | use async_std::prelude::*; |
143 | use async_std::future; |
144 | use std::io::{Error, ErrorKind}; |
145 | |
146 | let a = future::pending::<Result<_, Error>>(); |
147 | let b = future::ready(Err(Error::from(ErrorKind::Other))); |
148 | let c = future::ready(Ok(1u8)); |
149 | |
150 | let f = a.try_race(b).try_race(c); |
151 | assert_eq!(f.await?, 1u8); |
152 | # |
153 | # Ok(()) }) } |
154 | ``` |
155 | "# ] |
156 | #[cfg (feature = "unstable" )] |
157 | #[cfg_attr (feature = "docs" , doc(cfg(unstable)))] |
158 | fn try_race<F, T, E>( |
159 | self, |
160 | other: F |
161 | ) -> TryRace<Self, F> |
162 | where |
163 | Self: std::future::Future<Output = Result<T, E>> + Sized, |
164 | F: std::future::Future<Output = <Self as std::future::Future>::Output>, |
165 | { |
166 | TryRace::new(self, other) |
167 | } |
168 | |
169 | #[doc = r#" |
170 | Waits for two similarly-typed futures to complete. |
171 | |
172 | Awaits multiple futures simultaneously, returning the output of the |
173 | futures once both complete. |
174 | |
175 | This function returns a new future which polls both futures |
176 | concurrently. |
177 | |
178 | # Examples |
179 | |
180 | ``` |
181 | # async_std::task::block_on(async { |
182 | use async_std::prelude::*; |
183 | use async_std::future; |
184 | |
185 | let a = future::ready(1u8); |
186 | let b = future::ready(2u16); |
187 | |
188 | let f = a.join(b); |
189 | assert_eq!(f.await, (1u8, 2u16)); |
190 | # }); |
191 | ``` |
192 | "# ] |
193 | #[cfg (any(feature = "unstable" , feature = "docs" ))] |
194 | #[cfg_attr (feature = "docs" , doc(cfg(unstable)))] |
195 | fn join<F>( |
196 | self, |
197 | other: F |
198 | ) -> Join<Self, F> |
199 | where |
200 | Self: std::future::Future + Sized, |
201 | F: std::future::Future, |
202 | { |
203 | Join::new(self, other) |
204 | } |
205 | |
206 | #[doc = r#" |
207 | Waits for two similarly-typed fallible futures to complete. |
208 | |
209 | Awaits multiple futures simultaneously, returning all results once |
210 | complete. |
211 | |
212 | `try_join` is similar to [`join`], but returns an error immediately |
213 | if a future resolves to an error. |
214 | |
215 | [`join`]: #method.join |
216 | |
217 | # Examples |
218 | |
219 | ``` |
220 | # fn main() -> std::io::Result<()> { async_std::task::block_on(async { |
221 | # |
222 | use async_std::prelude::*; |
223 | use async_std::future; |
224 | |
225 | let a = future::ready(Err::<u8, &str>("Error")); |
226 | let b = future::ready(Ok(1u8)); |
227 | |
228 | let f = a.try_join(b); |
229 | assert_eq!(f.await, Err("Error")); |
230 | |
231 | let a = future::ready(Ok::<u8, String>(1u8)); |
232 | let b = future::ready(Ok::<u16, String>(2u16)); |
233 | |
234 | let f = a.try_join(b); |
235 | assert_eq!(f.await, Ok((1u8, 2u16))); |
236 | # |
237 | # Ok(()) }) } |
238 | ``` |
239 | "# ] |
240 | #[cfg (any(feature = "unstable" , feature = "docs" ))] |
241 | #[cfg_attr (feature = "docs" , doc(cfg(unstable)))] |
242 | fn try_join<F, A, B, E>( |
243 | self, |
244 | other: F |
245 | ) -> TryJoin<Self, F> |
246 | where |
247 | Self: std::future::Future<Output = Result<A, E>> + Sized, |
248 | F: std::future::Future<Output = Result<B, E>>, |
249 | { |
250 | TryJoin::new(self, other) |
251 | } |
252 | |
253 | #[doc = r#" |
254 | Waits for both the future and a timeout, if the timeout completes before |
255 | the future, it returns a TimeoutError. |
256 | |
257 | # Example |
258 | ``` |
259 | # async_std::task::block_on(async { |
260 | # |
261 | use std::time::Duration; |
262 | |
263 | use async_std::prelude::*; |
264 | use async_std::future; |
265 | |
266 | let fut = future::ready(0); |
267 | let dur = Duration::from_millis(100); |
268 | let res = fut.timeout(dur).await; |
269 | assert!(res.is_ok()); |
270 | |
271 | let fut = future::pending::<()>(); |
272 | let dur = Duration::from_millis(100); |
273 | let res = fut.timeout(dur).await; |
274 | assert!(res.is_err()) |
275 | # |
276 | # }); |
277 | ``` |
278 | "# ] |
279 | #[cfg (any(all(feature = "default" , feature = "unstable" ), feature = "docs" ))] |
280 | #[cfg_attr (feature = "docs" , doc(cfg(unstable)))] |
281 | fn timeout(self, dur: Duration) -> TimeoutFuture<Self> |
282 | where Self: Sized |
283 | { |
284 | TimeoutFuture::new(self, dur) |
285 | } |
286 | } |
287 | |
288 | #[cfg (any(feature = "std" , feature = "docs" ))] |
289 | impl<T: Future + ?Sized> FutureExt for T {} |
290 | |
291 | |