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