1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
use super::Join as JoinTrait;
use crate::utils::MaybeDone;
use core::fmt;
use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};
use pin_project::pin_project;
macro_rules! generate {
($(
$(#[$doc:meta])*
($Join:ident, <$($Fut:ident),*>),
)*) => ($(
$(#[$doc])*
#[pin_project]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[allow(non_snake_case)]
pub(crate) struct $Join<$($Fut: Future),*> {
$(#[pin] $Fut: MaybeDone<$Fut>,)*
}
impl<$($Fut),*> fmt::Debug for $Join<$($Fut),*>
where
$(
$Fut: Future + fmt::Debug,
$Fut::Output: fmt::Debug,
)*
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(stringify!($Join))
$(.field(stringify!($Fut), &self.$Fut))*
.finish()
}
}
impl<$($Fut: Future),*> $Join<$($Fut),*> {
fn new(($($Fut),*): ($($Fut),*)) -> Self {
Self {
$($Fut: MaybeDone::new($Fut)),*
}
}
}
#[async_trait::async_trait(?Send)]
impl<$($Fut),*> JoinTrait for ($($Fut),*)
where
$(
$Fut: Future,
)*
{
type Output = ($($Fut::Output),*);
async fn join(self) -> Self::Output {
$Join::new(self).await
}
}
impl<$($Fut: Future),*> Future for $Join<$($Fut),*> {
type Output = ($($Fut::Output),*);
fn poll(
self: Pin<&mut Self>, cx: &mut Context<'_>
) -> Poll<Self::Output> {
let mut all_done = true;
let mut futures = self.project();
$(
all_done &= futures.$Fut.as_mut().poll(cx).is_ready();
)*
if all_done {
Poll::Ready(($(futures.$Fut.take().unwrap()), *))
} else {
Poll::Pending
}
}
}
)*)
}
generate! {
/// Waits for two similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join2, <A, B>),
/// Waits for three similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join3, <A, B, C>),
/// Waits for four similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join4, <A, B, C, D>),
/// Waits for five similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join5, <A, B, C, D, E>),
/// Waits for six similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join6, <A, B, C, D, E, F>),
/// Waits for seven similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join7, <A, B, C, D, E, F, G>),
/// Waits for eight similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join8, <A, B, C, D, E, F, G, H>),
/// Waits for nine similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join9, <A, B, C, D, E, F, G, H, I>),
/// Waits for ten similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join10, <A, B, C, D, E, F, G, H, I, J>),
/// Waits for eleven similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join11, <A, B, C, D, E, F, G, H, I, J, K>),
/// Waits for twelve similarly-typed futures to complete.
///
/// Awaits multiple futures simultaneously, returning the output of the
/// futures once both complete.
(Join12, <A, B, C, D, E, F, G, H, I, J, K, L>),
}