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