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}
337