futures_util/async_await/
select_mod.rs

1//! The `select` macro.
2
3macro_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)]
309pub use futures_macro::select_internal;
310
311#[allow(unreachable_pub)]
312#[doc(hidden)]
313pub use futures_macro::select_biased_internal;
314
315document_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}