1 //! The `join` macro. 2 3 use proc_macro_hack::proc_macro_hack; 4 5 macro_rules! document_join_macro { 6 ($join:item $try_join:item) => { 7 /// Polls multiple futures simultaneously, returning a tuple 8 /// of all results once complete. 9 /// 10 /// While `join!(a, b)` is similar to `(a.await, b.await)`, 11 /// `join!` polls both futures concurrently and therefore is more efficient. 12 /// 13 /// This macro is only usable inside of async functions, closures, and blocks. 14 /// It is also gated behind the `async-await` feature of this library, which is 15 /// activated by default. 16 /// 17 /// # Examples 18 /// 19 /// ``` 20 /// # futures::executor::block_on(async { 21 /// use futures::join; 22 /// 23 /// let a = async { 1 }; 24 /// let b = async { 2 }; 25 /// assert_eq!(join!(a, b), (1, 2)); 26 /// 27 /// // `join!` is variadic, so you can pass any number of futures 28 /// let c = async { 3 }; 29 /// let d = async { 4 }; 30 /// let e = async { 5 }; 31 /// assert_eq!(join!(c, d, e), (3, 4, 5)); 32 /// # }); 33 /// ``` 34 $join 35 36 /// Polls multiple futures simultaneously, resolving to a [`Result`] containing 37 /// either a tuple of the successful outputs or an error. 38 /// 39 /// `try_join!` is similar to [`join!`], but completes immediately if any of 40 /// the futures return an error. 41 /// 42 /// This macro is only usable inside of async functions, closures, and blocks. 43 /// It is also gated behind the `async-await` feature of this library, which is 44 /// activated by default. 45 /// 46 /// # Examples 47 /// 48 /// When used on multiple futures that return `Ok`, `try_join!` will return 49 /// `Ok` of a tuple of the values: 50 /// 51 /// ``` 52 /// # futures::executor::block_on(async { 53 /// use futures::try_join; 54 /// 55 /// let a = async { Ok::<i32, i32>(1) }; 56 /// let b = async { Ok::<i32, i32>(2) }; 57 /// assert_eq!(try_join!(a, b), Ok((1, 2))); 58 /// 59 /// // `try_join!` is variadic, so you can pass any number of futures 60 /// let c = async { Ok::<i32, i32>(3) }; 61 /// let d = async { Ok::<i32, i32>(4) }; 62 /// let e = async { Ok::<i32, i32>(5) }; 63 /// assert_eq!(try_join!(c, d, e), Ok((3, 4, 5))); 64 /// # }); 65 /// ``` 66 /// 67 /// If one of the futures resolves to an error, `try_join!` will return 68 /// that error: 69 /// 70 /// ``` 71 /// # futures::executor::block_on(async { 72 /// use futures::try_join; 73 /// 74 /// let a = async { Ok::<i32, i32>(1) }; 75 /// let b = async { Err::<u64, i32>(2) }; 76 /// 77 /// assert_eq!(try_join!(a, b), Err(2)); 78 /// # }); 79 /// ``` 80 $try_join 81 } 82 } 83 84 #[doc(hidden)] 85 #[proc_macro_hack(support_nested, only_hack_old_rustc)] 86 pub use futures_macro::join_internal; 87 88 #[doc(hidden)] 89 #[proc_macro_hack(support_nested, only_hack_old_rustc)] 90 pub use futures_macro::try_join_internal; 91 92 document_join_macro! { 93 #[macro_export] 94 macro_rules! join { 95 ($($tokens:tt)*) => {{ 96 use $crate::__private as __futures_crate; 97 $crate::join_internal! { 98 $( $tokens )* 99 } 100 }} 101 } 102 103 #[macro_export] 104 macro_rules! try_join { 105 ($($tokens:tt)*) => {{ 106 use $crate::__private as __futures_crate; 107 $crate::try_join_internal! { 108 $( $tokens )* 109 } 110 }} 111 } 112 } 113