• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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