1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
//! The `select` macro. /// Polls multiple futures simultaneously, executing the branch for the future /// that finishes first. /// /// `select!` can select over futures with different output types, but each /// branch has to have the same return type. Inside each branch, the respective /// future's output is available via a variable with the same name as the future. /// /// This macro is only usable inside of async functions, closures, and blocks. /// /// # Examples /// /// ``` /// #![feature(pin, async_await, await_macro, futures_api)] /// # futures::executor::block_on(async { /// use futures::{select, future}; /// let mut a = future::ready(4); /// let mut b: future::Empty<()> = future::empty(); /// /// let res = select! { /// a => a + 1, /// b => 0, /// }; /// assert_eq!(res, 5); /// # }); /// ``` #[macro_export] macro_rules! select { () => { compile_error!("The `select!` macro requires at least one branch") }; ($( $name:ident => $body:expr, )*) => { { // Require all arguments to be `Unpin` so that we don't have to pin them, // allowing uncompleted futures to be reused by the caller after the // `select!` resolves. $( $crate::async_await::assert_unpin(&$name); )* #[allow(bad_style)] enum __PrivResult<$($name,)*> { $( $name($name), )* } let __priv_res = await!($crate::future::poll_fn(|cx| { $( match $crate::core_reexport::future::Future::poll( $crate::core_reexport::pin::PinMut::new(&mut $name), cx) { $crate::core_reexport::task::Poll::Ready(x) => return $crate::core_reexport::task::Poll::Ready(__PrivResult::$name(x)), $crate::core_reexport::task::Poll::Pending => {}, } )* $crate::core_reexport::task::Poll::Pending })); match __priv_res { $( __PrivResult::$name($name) => { let _ = $name; // Suppress "unused" warning for binding name $body } )* } } }; }