Coverage Report

Created: 2025-06-24 06:17

/rust/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.28/src/future/join.rs
Line
Count
Source (jump to first uncovered line)
1
#![allow(non_snake_case)]
2
3
use super::assert_future;
4
use crate::future::{maybe_done, MaybeDone};
5
use core::fmt;
6
use core::pin::Pin;
7
use futures_core::future::{FusedFuture, Future};
8
use futures_core::task::{Context, Poll};
9
use pin_project_lite::pin_project;
10
11
macro_rules! generate {
12
    ($(
13
        $(#[$doc:meta])*
14
        ($Join:ident, <$($Fut:ident),*>),
15
    )*) => ($(
16
        pin_project! {
17
            $(#[$doc])*
18
            #[must_use = "futures do nothing unless you `.await` or poll them"]
19
            pub struct $Join<$($Fut: Future),*> {
20
                $(#[pin] $Fut: MaybeDone<$Fut>,)*
21
            }
22
        }
23
24
        impl<$($Fut),*> fmt::Debug for $Join<$($Fut),*>
25
        where
26
            $(
27
                $Fut: Future + fmt::Debug,
28
                $Fut::Output: fmt::Debug,
29
            )*
30
        {
31
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32
0
                f.debug_struct(stringify!($Join))
33
0
                    $(.field(stringify!($Fut), &self.$Fut))*
34
0
                    .finish()
35
0
            }
Unexecuted instantiation: <futures_util::future::join::Join<_, _> as core::fmt::Debug>::fmt
Unexecuted instantiation: <futures_util::future::join::Join3<_, _, _> as core::fmt::Debug>::fmt
Unexecuted instantiation: <futures_util::future::join::Join4<_, _, _, _> as core::fmt::Debug>::fmt
Unexecuted instantiation: <futures_util::future::join::Join5<_, _, _, _, _> as core::fmt::Debug>::fmt
36
        }
37
38
        impl<$($Fut: Future),*> $Join<$($Fut),*> {
39
0
            fn new($($Fut: $Fut),*) -> Self {
40
0
                Self {
41
0
                    $($Fut: maybe_done($Fut)),*
42
0
                }
43
0
            }
Unexecuted instantiation: <futures_util::future::join::Join<_, _>>::new
Unexecuted instantiation: <futures_util::future::join::Join3<_, _, _>>::new
Unexecuted instantiation: <futures_util::future::join::Join4<_, _, _, _>>::new
Unexecuted instantiation: <futures_util::future::join::Join5<_, _, _, _, _>>::new
44
        }
45
46
        impl<$($Fut: Future),*> Future for $Join<$($Fut),*> {
47
            type Output = ($($Fut::Output),*);
48
49
0
            fn poll(
50
0
                self: Pin<&mut Self>, cx: &mut Context<'_>
51
0
            ) -> Poll<Self::Output> {
52
0
                let mut all_done = true;
53
0
                let mut futures = self.project();
54
0
                $(
55
0
                    all_done &= futures.$Fut.as_mut().poll(cx).is_ready();
56
0
                )*
57
0
58
0
                if all_done {
59
0
                    Poll::Ready(($(futures.$Fut.take_output().unwrap()), *))
60
                } else {
61
0
                    Poll::Pending
62
                }
63
0
            }
Unexecuted instantiation: <futures_util::future::join::Join<_, _> as core::future::future::Future>::poll
Unexecuted instantiation: <futures_util::future::join::Join3<_, _, _> as core::future::future::Future>::poll
Unexecuted instantiation: <futures_util::future::join::Join4<_, _, _, _> as core::future::future::Future>::poll
Unexecuted instantiation: <futures_util::future::join::Join5<_, _, _, _, _> as core::future::future::Future>::poll
64
        }
65
66
        impl<$($Fut: FusedFuture),*> FusedFuture for $Join<$($Fut),*> {
67
0
            fn is_terminated(&self) -> bool {
68
                $(
69
0
                    self.$Fut.is_terminated()
70
                ) && *
71
0
            }
Unexecuted instantiation: <futures_util::future::join::Join<_, _> as futures_core::future::FusedFuture>::is_terminated
Unexecuted instantiation: <futures_util::future::join::Join3<_, _, _> as futures_core::future::FusedFuture>::is_terminated
Unexecuted instantiation: <futures_util::future::join::Join4<_, _, _, _> as futures_core::future::FusedFuture>::is_terminated
Unexecuted instantiation: <futures_util::future::join::Join5<_, _, _, _, _> as futures_core::future::FusedFuture>::is_terminated
72
        }
73
    )*)
74
}
75
76
generate! {
77
    /// Future for the [`join`](join()) function.
78
    (Join, <Fut1, Fut2>),
79
80
    /// Future for the [`join3`] function.
81
    (Join3, <Fut1, Fut2, Fut3>),
82
83
    /// Future for the [`join4`] function.
84
    (Join4, <Fut1, Fut2, Fut3, Fut4>),
85
86
    /// Future for the [`join5`] function.
87
    (Join5, <Fut1, Fut2, Fut3, Fut4, Fut5>),
88
}
89
90
/// Joins the result of two futures, waiting for them both to complete.
91
///
92
/// This function will return a new future which awaits both futures to
93
/// complete. The returned future will finish with a tuple of both results.
94
///
95
/// Note that this function consumes the passed futures and returns a
96
/// wrapped version of it.
97
///
98
/// # Examples
99
///
100
/// ```
101
/// # futures::executor::block_on(async {
102
/// use futures::future;
103
///
104
/// let a = async { 1 };
105
/// let b = async { 2 };
106
/// let pair = future::join(a, b);
107
///
108
/// assert_eq!(pair.await, (1, 2));
109
/// # });
110
/// ```
111
0
pub fn join<Fut1, Fut2>(future1: Fut1, future2: Fut2) -> Join<Fut1, Fut2>
112
0
where
113
0
    Fut1: Future,
114
0
    Fut2: Future,
115
0
{
116
0
    let f = Join::new(future1, future2);
117
0
    assert_future::<(Fut1::Output, Fut2::Output), _>(f)
118
0
}
119
120
/// Same as [`join`](join()), but with more futures.
121
///
122
/// # Examples
123
///
124
/// ```
125
/// # futures::executor::block_on(async {
126
/// use futures::future;
127
///
128
/// let a = async { 1 };
129
/// let b = async { 2 };
130
/// let c = async { 3 };
131
/// let tuple = future::join3(a, b, c);
132
///
133
/// assert_eq!(tuple.await, (1, 2, 3));
134
/// # });
135
/// ```
136
0
pub fn join3<Fut1, Fut2, Fut3>(
137
0
    future1: Fut1,
138
0
    future2: Fut2,
139
0
    future3: Fut3,
140
0
) -> Join3<Fut1, Fut2, Fut3>
141
0
where
142
0
    Fut1: Future,
143
0
    Fut2: Future,
144
0
    Fut3: Future,
145
0
{
146
0
    let f = Join3::new(future1, future2, future3);
147
0
    assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output), _>(f)
148
0
}
149
150
/// Same as [`join`](join()), but with more futures.
151
///
152
/// # Examples
153
///
154
/// ```
155
/// # futures::executor::block_on(async {
156
/// use futures::future;
157
///
158
/// let a = async { 1 };
159
/// let b = async { 2 };
160
/// let c = async { 3 };
161
/// let d = async { 4 };
162
/// let tuple = future::join4(a, b, c, d);
163
///
164
/// assert_eq!(tuple.await, (1, 2, 3, 4));
165
/// # });
166
/// ```
167
0
pub fn join4<Fut1, Fut2, Fut3, Fut4>(
168
0
    future1: Fut1,
169
0
    future2: Fut2,
170
0
    future3: Fut3,
171
0
    future4: Fut4,
172
0
) -> Join4<Fut1, Fut2, Fut3, Fut4>
173
0
where
174
0
    Fut1: Future,
175
0
    Fut2: Future,
176
0
    Fut3: Future,
177
0
    Fut4: Future,
178
0
{
179
0
    let f = Join4::new(future1, future2, future3, future4);
180
0
    assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output), _>(f)
181
0
}
182
183
/// Same as [`join`](join()), but with more futures.
184
///
185
/// # Examples
186
///
187
/// ```
188
/// # futures::executor::block_on(async {
189
/// use futures::future;
190
///
191
/// let a = async { 1 };
192
/// let b = async { 2 };
193
/// let c = async { 3 };
194
/// let d = async { 4 };
195
/// let e = async { 5 };
196
/// let tuple = future::join5(a, b, c, d, e);
197
///
198
/// assert_eq!(tuple.await, (1, 2, 3, 4, 5));
199
/// # });
200
/// ```
201
0
pub fn join5<Fut1, Fut2, Fut3, Fut4, Fut5>(
202
0
    future1: Fut1,
203
0
    future2: Fut2,
204
0
    future3: Fut3,
205
0
    future4: Fut4,
206
0
    future5: Fut5,
207
0
) -> Join5<Fut1, Fut2, Fut3, Fut4, Fut5>
208
0
where
209
0
    Fut1: Future,
210
0
    Fut2: Future,
211
0
    Fut3: Future,
212
0
    Fut4: Future,
213
0
    Fut5: Future,
214
0
{
215
0
    let f = Join5::new(future1, future2, future3, future4, future5);
216
0
    assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output, Fut5::Output), _>(f)
217
0
}