1 | //! The `select` macro. |
2 | |
3 | macro_rules! document_select_macro { |
4 | // This branch is required for `futures 0.3.1`, from before select_biased was introduced |
5 | ($select:item) => { |
6 | /// Polls multiple futures and streams simultaneously, executing the branch |
7 | /// for the future that finishes first. If multiple futures are ready, |
8 | /// one will be pseudo-randomly selected at runtime. Futures directly |
9 | /// passed to `select!` must be `Unpin` and implement `FusedFuture`. |
10 | /// |
11 | /// If an expression which yields a `Future` is passed to `select!` |
12 | /// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin` |
13 | /// requirement is relaxed, since the macro will pin the resulting `Future` |
14 | /// on the stack. However the `Future` returned by the expression must |
15 | /// still implement `FusedFuture`. |
16 | /// |
17 | /// Futures and streams which are not already fused can be fused using the |
18 | /// `.fuse()` method. Note, though, that fusing a future or stream directly |
19 | /// in the call to `select!` will not be enough to prevent it from being |
20 | /// polled after completion if the `select!` call is in a loop, so when |
21 | /// `select!`ing in a loop, users should take care to `fuse()` outside of |
22 | /// the loop. |
23 | /// |
24 | /// `select!` can be used as an expression and will return the return |
25 | /// value of the selected branch. For this reason the return type of every |
26 | /// branch in a `select!` must be the same. |
27 | /// |
28 | /// This macro is only usable inside of async functions, closures, and blocks. |
29 | /// It is also gated behind the `async-await` feature of this library, which is |
30 | /// activated by default. |
31 | /// |
32 | /// # Examples |
33 | /// |
34 | /// ``` |
35 | /// # futures::executor::block_on(async { |
36 | /// use futures::future; |
37 | /// use futures::select; |
38 | /// let mut a = future::ready(4); |
39 | /// let mut b = future::pending::<()>(); |
40 | /// |
41 | /// let res = select! { |
42 | /// a_res = a => a_res + 1, |
43 | /// _ = b => 0, |
44 | /// }; |
45 | /// assert_eq!(res, 5); |
46 | /// # }); |
47 | /// ``` |
48 | /// |
49 | /// ``` |
50 | /// # futures::executor::block_on(async { |
51 | /// use futures::future; |
52 | /// use futures::stream::{self, StreamExt}; |
53 | /// use futures::select; |
54 | /// let mut st = stream::iter(vec![2]).fuse(); |
55 | /// let mut fut = future::pending::<()>(); |
56 | /// |
57 | /// select! { |
58 | /// x = st.next() => assert_eq!(Some(2), x), |
59 | /// _ = fut => panic!(), |
60 | /// }; |
61 | /// # }); |
62 | /// ``` |
63 | /// |
64 | /// As described earlier, `select` can directly select on expressions |
65 | /// which return `Future`s - even if those do not implement `Unpin`: |
66 | /// |
67 | /// ``` |
68 | /// # futures::executor::block_on(async { |
69 | /// use futures::future::FutureExt; |
70 | /// use futures::select; |
71 | /// |
72 | /// // Calling the following async fn returns a Future which does not |
73 | /// // implement Unpin |
74 | /// async fn async_identity_fn(arg: usize) -> usize { |
75 | /// arg |
76 | /// } |
77 | /// |
78 | /// let res = select! { |
79 | /// a_res = async_identity_fn(62).fuse() => a_res + 1, |
80 | /// b_res = async_identity_fn(13).fuse() => b_res, |
81 | /// }; |
82 | /// assert!(res == 63 || res == 13); |
83 | /// # }); |
84 | /// ``` |
85 | /// |
86 | /// If a similar async function is called outside of `select` to produce |
87 | /// a `Future`, the `Future` must be pinned in order to be able to pass |
88 | /// it to `select`. This can be achieved via `Box::pin` for pinning a |
89 | /// `Future` on the heap or the `pin_mut!` macro for pinning a `Future` |
90 | /// on the stack. |
91 | /// |
92 | /// ``` |
93 | /// # futures::executor::block_on(async { |
94 | /// use futures::future::FutureExt; |
95 | /// use futures::select; |
96 | /// use futures::pin_mut; |
97 | /// |
98 | /// // Calling the following async fn returns a Future which does not |
99 | /// // implement Unpin |
100 | /// async fn async_identity_fn(arg: usize) -> usize { |
101 | /// arg |
102 | /// } |
103 | /// |
104 | /// let fut_1 = async_identity_fn(1).fuse(); |
105 | /// let fut_2 = async_identity_fn(2).fuse(); |
106 | /// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap |
107 | /// pin_mut!(fut_2); // Pins the Future on the stack |
108 | /// |
109 | /// let res = select! { |
110 | /// a_res = fut_1 => a_res, |
111 | /// b_res = fut_2 => b_res, |
112 | /// }; |
113 | /// assert!(res == 1 || res == 2); |
114 | /// # }); |
115 | /// ``` |
116 | /// |
117 | /// `select` also accepts a `complete` branch and a `default` branch. |
118 | /// `complete` will run if all futures and streams have already been |
119 | /// exhausted. `default` will run if no futures or streams are |
120 | /// immediately ready. `complete` takes priority over `default` in |
121 | /// the case where all futures have completed. |
122 | /// A motivating use-case for passing `Future`s by name as well as for |
123 | /// `complete` blocks is to call `select!` in a loop, which is |
124 | /// demonstrated in the following example: |
125 | /// |
126 | /// ``` |
127 | /// # futures::executor::block_on(async { |
128 | /// use futures::future; |
129 | /// use futures::select; |
130 | /// let mut a_fut = future::ready(4); |
131 | /// let mut b_fut = future::ready(6); |
132 | /// let mut total = 0; |
133 | /// |
134 | /// loop { |
135 | /// select! { |
136 | /// a = a_fut => total += a, |
137 | /// b = b_fut => total += b, |
138 | /// complete => break, |
139 | /// default => panic!(), // never runs (futures run first, then complete) |
140 | /// }; |
141 | /// } |
142 | /// assert_eq!(total, 10); |
143 | /// # }); |
144 | /// ``` |
145 | /// |
146 | /// Note that the futures that have been matched over can still be mutated |
147 | /// from inside the `select!` block's branches. This can be used to implement |
148 | /// more complex behavior such as timer resets or writing into the head of |
149 | /// a stream. |
150 | $select |
151 | }; |
152 | |
153 | ($select:item $select_biased:item) => { |
154 | document_select_macro!($select); |
155 | |
156 | /// Polls multiple futures and streams simultaneously, executing the branch |
157 | /// for the future that finishes first. Unlike [`select!`], if multiple futures are ready, |
158 | /// one will be selected in order of declaration. Futures directly |
159 | /// passed to `select_biased!` must be `Unpin` and implement `FusedFuture`. |
160 | /// |
161 | /// If an expression which yields a `Future` is passed to `select_biased!` |
162 | /// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin` |
163 | /// requirement is relaxed, since the macro will pin the resulting `Future` |
164 | /// on the stack. However the `Future` returned by the expression must |
165 | /// still implement `FusedFuture`. |
166 | /// |
167 | /// Futures and streams which are not already fused can be fused using the |
168 | /// `.fuse()` method. Note, though, that fusing a future or stream directly |
169 | /// in the call to `select_biased!` will not be enough to prevent it from being |
170 | /// polled after completion if the `select_biased!` call is in a loop, so when |
171 | /// `select_biased!`ing in a loop, users should take care to `fuse()` outside of |
172 | /// the loop. |
173 | /// |
174 | /// `select_biased!` can be used as an expression and will return the return |
175 | /// value of the selected branch. For this reason the return type of every |
176 | /// branch in a `select_biased!` must be the same. |
177 | /// |
178 | /// This macro is only usable inside of async functions, closures, and blocks. |
179 | /// It is also gated behind the `async-await` feature of this library, which is |
180 | /// activated by default. |
181 | /// |
182 | /// # Examples |
183 | /// |
184 | /// ``` |
185 | /// # futures::executor::block_on(async { |
186 | /// use futures::future; |
187 | /// use futures::select_biased; |
188 | /// let mut a = future::ready(4); |
189 | /// let mut b = future::pending::<()>(); |
190 | /// |
191 | /// let res = select_biased! { |
192 | /// a_res = a => a_res + 1, |
193 | /// _ = b => 0, |
194 | /// }; |
195 | /// assert_eq!(res, 5); |
196 | /// # }); |
197 | /// ``` |
198 | /// |
199 | /// ``` |
200 | /// # futures::executor::block_on(async { |
201 | /// use futures::future; |
202 | /// use futures::stream::{self, StreamExt}; |
203 | /// use futures::select_biased; |
204 | /// let mut st = stream::iter(vec![2]).fuse(); |
205 | /// let mut fut = future::pending::<()>(); |
206 | /// |
207 | /// select_biased! { |
208 | /// x = st.next() => assert_eq!(Some(2), x), |
209 | /// _ = fut => panic!(), |
210 | /// }; |
211 | /// # }); |
212 | /// ``` |
213 | /// |
214 | /// As described earlier, `select_biased` can directly select on expressions |
215 | /// which return `Future`s - even if those do not implement `Unpin`: |
216 | /// |
217 | /// ``` |
218 | /// # futures::executor::block_on(async { |
219 | /// use futures::future::FutureExt; |
220 | /// use futures::select_biased; |
221 | /// |
222 | /// // Calling the following async fn returns a Future which does not |
223 | /// // implement Unpin |
224 | /// async fn async_identity_fn(arg: usize) -> usize { |
225 | /// arg |
226 | /// } |
227 | /// |
228 | /// let res = select_biased! { |
229 | /// a_res = async_identity_fn(62).fuse() => a_res + 1, |
230 | /// b_res = async_identity_fn(13).fuse() => b_res, |
231 | /// }; |
232 | /// assert!(res == 63 || res == 12); |
233 | /// # }); |
234 | /// ``` |
235 | /// |
236 | /// If a similar async function is called outside of `select_biased` to produce |
237 | /// a `Future`, the `Future` must be pinned in order to be able to pass |
238 | /// it to `select_biased`. This can be achieved via `Box::pin` for pinning a |
239 | /// `Future` on the heap or the `pin_mut!` macro for pinning a `Future` |
240 | /// on the stack. |
241 | /// |
242 | /// ``` |
243 | /// # futures::executor::block_on(async { |
244 | /// use futures::future::FutureExt; |
245 | /// use futures::select_biased; |
246 | /// use futures::pin_mut; |
247 | /// |
248 | /// // Calling the following async fn returns a Future which does not |
249 | /// // implement Unpin |
250 | /// async fn async_identity_fn(arg: usize) -> usize { |
251 | /// arg |
252 | /// } |
253 | /// |
254 | /// let fut_1 = async_identity_fn(1).fuse(); |
255 | /// let fut_2 = async_identity_fn(2).fuse(); |
256 | /// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap |
257 | /// pin_mut!(fut_2); // Pins the Future on the stack |
258 | /// |
259 | /// let res = select_biased! { |
260 | /// a_res = fut_1 => a_res, |
261 | /// b_res = fut_2 => b_res, |
262 | /// }; |
263 | /// assert!(res == 1 || res == 2); |
264 | /// # }); |
265 | /// ``` |
266 | /// |
267 | /// `select_biased` also accepts a `complete` branch and a `default` branch. |
268 | /// `complete` will run if all futures and streams have already been |
269 | /// exhausted. `default` will run if no futures or streams are |
270 | /// immediately ready. `complete` takes priority over `default` in |
271 | /// the case where all futures have completed. |
272 | /// A motivating use-case for passing `Future`s by name as well as for |
273 | /// `complete` blocks is to call `select_biased!` in a loop, which is |
274 | /// demonstrated in the following example: |
275 | /// |
276 | /// ``` |
277 | /// # futures::executor::block_on(async { |
278 | /// use futures::future; |
279 | /// use futures::select_biased; |
280 | /// let mut a_fut = future::ready(4); |
281 | /// let mut b_fut = future::ready(6); |
282 | /// let mut total = 0; |
283 | /// |
284 | /// loop { |
285 | /// select_biased! { |
286 | /// a = a_fut => total += a, |
287 | /// b = b_fut => total += b, |
288 | /// complete => break, |
289 | /// default => panic!(), // never runs (futures run first, then complete) |
290 | /// }; |
291 | /// } |
292 | /// assert_eq!(total, 10); |
293 | /// # }); |
294 | /// ``` |
295 | /// |
296 | /// Note that the futures that have been matched over can still be mutated |
297 | /// from inside the `select_biased!` block's branches. This can be used to implement |
298 | /// more complex behavior such as timer resets or writing into the head of |
299 | /// a stream. |
300 | /// |
301 | /// [`select!`]: macro.select.html |
302 | $select_biased |
303 | }; |
304 | } |
305 | |
306 | #[cfg (feature = "std" )] |
307 | #[allow (unreachable_pub)] |
308 | #[doc (hidden)] |
309 | pub use futures_macro::select_internal; |
310 | |
311 | #[allow (unreachable_pub)] |
312 | #[doc (hidden)] |
313 | pub use futures_macro::select_biased_internal; |
314 | |
315 | document_select_macro! { |
316 | #[cfg (feature = "std" )] |
317 | #[macro_export ] |
318 | macro_rules! select { |
319 | ($($tokens:tt)*) => {{ |
320 | use $crate::__private as __futures_crate; |
321 | $crate::select_internal! { |
322 | $( $tokens )* |
323 | } |
324 | }} |
325 | } |
326 | |
327 | #[macro_export ] |
328 | macro_rules! select_biased { |
329 | ($($tokens:tt)*) => {{ |
330 | use $crate::__private as __futures_crate; |
331 | $crate::select_biased_internal! { |
332 | $( $tokens )* |
333 | } |
334 | }} |
335 | } |
336 | } |
337 | |