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