#[macro_export]
macro_rules! join {
() => {
()
};
(biased; $($future:expr),+ $(,)?) => {
$crate::__join!(@munch join [biased] [] [] $($future,)+)
};
($($future:expr),+ $(,)?) => {
$crate::__join!(@munch join [fair] [] [] $($future,)+)
};
}
#[macro_export]
macro_rules! try_join {
() => {
::core::result::Result::Ok(())
};
(biased; $($future:expr),+ $(,)?) => {
$crate::__join!(@munch try_join [biased] [] [] $($future,)+)
};
($($future:expr),+ $(,)?) => {
$crate::__join!(@munch try_join [fair] [] [] $($future,)+)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __join {
(@munch $kind:ident $mode:tt [$($done:tt)*] [$($all:tt)*] $future:expr, $($rest:tt)*) => {
$crate::__join!(@munch $kind $mode [$($done)* ([$($all)*] $future)] [$($all)* _] $($rest)*)
};
(@munch $kind:ident [$mode:ident] [$( ([$($skip:tt)*] $future:expr) )+] [$($all:tt)*]) => {{
let mut __futures = ($(
::core::pin::pin!($crate::macros::support::MaybeDone::new(
::core::future::IntoFuture::into_future($future),
)),
)+);
let mut __next: u32 = 0;
$crate::macros::support::poll_fn(|__cx: &mut ::core::task::Context<'_>| {
if !$crate::macros::support::proceed(__cx) {
return ::core::task::Poll::Pending;
}
let __count: u32 = $crate::__count!($($all)*);
let __start: u32 = $crate::__join!(@start $mode __next);
__next = (__start + 1) % __count;
let mut __done = true;
for __turn in 0..__count {
let __index = (__start + __turn) % __count;
$(
if __index == $crate::__count!($($skip)*) {
let ($($skip,)* __future, ..) = &mut __futures;
if $crate::macros::support::MaybeDone::poll_done(::core::pin::Pin::as_mut(__future), __cx) {
$crate::__join!(@check $kind __future);
} else {
__done = false;
}
continue;
}
)+
}
if !__done {
return ::core::task::Poll::Pending;
}
::core::task::Poll::Ready($crate::__join!(@output $kind ($({
let ($($skip,)* __future, ..) = &mut __futures;
match $crate::macros::support::MaybeDone::take_output(::core::pin::Pin::as_mut(__future)) {
::core::option::Option::Some(__output) => __output,
::core::option::Option::None => ::core::unreachable!("a joined output taken twice"),
}
},)+)))
})
.await
}};
(@start biased $next:ident) => {
0
};
(@start fair $next:ident) => {
$next
};
(@check join $future:ident) => {};
(@check try_join $future:ident) => {
if let ::core::option::Option::Some(::core::result::Result::Err(_)) =
$crate::macros::support::MaybeDone::output_mut(::core::pin::Pin::as_mut($future))
{
if let ::core::option::Option::Some(::core::result::Result::Err(__error)) =
$crate::macros::support::MaybeDone::take_output(::core::pin::Pin::as_mut($future))
{
return ::core::task::Poll::Ready(::core::result::Result::Err(__error));
}
}
};
(@output join ($($output:expr,)+)) => {
($($output,)+)
};
(@output try_join ($($output:expr,)+)) => {
::core::result::Result::Ok(($(
match $output {
::core::result::Result::Ok(__value) => __value,
::core::result::Result::Err(_) => ::core::unreachable!("a `try_join!` error not given at once"),
},
)+))
};
}