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