1#[macro_export]
32macro_rules! join {
33 () => {
34 ()
35 };
36 (biased; $($future:expr),+ $(,)?) => {
37 $crate::__join!(@munch join [biased] [] [] $($future,)+)
38 };
39 ($($future:expr),+ $(,)?) => {
40 $crate::__join!(@munch join [fair] [] [] $($future,)+)
41 };
42}
43
44#[macro_export]
66macro_rules! try_join {
67 () => {
68 ::core::result::Result::Ok(())
69 };
70 (biased; $($future:expr),+ $(,)?) => {
71 $crate::__join!(@munch try_join [biased] [] [] $($future,)+)
72 };
73 ($($future:expr),+ $(,)?) => {
74 $crate::__join!(@munch try_join [fair] [] [] $($future,)+)
75 };
76}
77
78#[doc(hidden)]
81#[macro_export]
82macro_rules! __join {
83 (@munch $kind:ident $mode:tt [$($done:tt)*] [$($all:tt)*] $future:expr, $($rest:tt)*) => {
84 $crate::__join!(@munch $kind $mode [$($done)* ([$($all)*] $future)] [$($all)* _] $($rest)*)
85 };
86 (@munch $kind:ident [$mode:ident] [$( ([$($skip:tt)*] $future:expr) )+] [$($all:tt)*]) => {{
87 let mut __futures = ($(
88 ::core::pin::pin!($crate::macros::support::MaybeDone::new(
89 ::core::future::IntoFuture::into_future($future),
90 )),
91 )+);
92 let mut __next: u32 = 0;
93 $crate::macros::support::poll_fn(|__cx: &mut ::core::task::Context<'_>| {
94 if !$crate::macros::support::proceed(__cx) {
95 return ::core::task::Poll::Pending;
96 }
97 let __count: u32 = $crate::__count!($($all)*);
98 let __start: u32 = $crate::__join!(@start $mode __next);
99 __next = (__start + 1) % __count;
100 let mut __done = true;
101 for __turn in 0..__count {
102 let __index = (__start + __turn) % __count;
103 $(
104 if __index == $crate::__count!($($skip)*) {
105 let ($($skip,)* __future, ..) = &mut __futures;
106 if $crate::macros::support::MaybeDone::poll_done(::core::pin::Pin::as_mut(__future), __cx) {
107 $crate::__join!(@check $kind __future);
108 } else {
109 __done = false;
110 }
111 continue;
112 }
113 )+
114 }
115 if !__done {
116 return ::core::task::Poll::Pending;
117 }
118 ::core::task::Poll::Ready($crate::__join!(@output $kind ($({
119 let ($($skip,)* __future, ..) = &mut __futures;
120 match $crate::macros::support::MaybeDone::take_output(::core::pin::Pin::as_mut(__future)) {
121 ::core::option::Option::Some(__output) => __output,
122 ::core::option::Option::None => ::core::unreachable!("a joined output taken twice"),
123 }
124 },)+)))
125 })
126 .await
127 }};
128
129 (@start biased $next:ident) => {
130 0
131 };
132 (@start fair $next:ident) => {
133 $next
134 };
135
136 (@check join $future:ident) => {};
138 (@check try_join $future:ident) => {
139 if let ::core::option::Option::Some(::core::result::Result::Err(_)) =
140 $crate::macros::support::MaybeDone::output_mut(::core::pin::Pin::as_mut($future))
141 {
142 if let ::core::option::Option::Some(::core::result::Result::Err(__error)) =
143 $crate::macros::support::MaybeDone::take_output(::core::pin::Pin::as_mut($future))
144 {
145 return ::core::task::Poll::Ready(::core::result::Result::Err(__error));
146 }
147 }
148 };
149
150 (@output join ($($output:expr,)+)) => {
151 ($($output,)+)
152 };
153 (@output try_join ($($output:expr,)+)) => {
154 ::core::result::Result::Ok(($(
155 match $output {
156 ::core::result::Result::Ok(__value) => __value,
157 ::core::result::Result::Err(_) => ::core::unreachable!("a `try_join!` error not given at once"),
158 },
159 )+))
160 };
161}