1#![allow(non_snake_case)]
7
8use std::future::Future;
9use std::pin::Pin;
10use std::task::Context;
11use std::task::Poll;
12
13use futures::future::maybe_done;
14use futures::future::FutureExt;
15use futures::future::MaybeDone;
16
17pub enum SelectResult<F: Future> {
18 Pending(F),
19 Finished(F::Output),
20}
21
22macro_rules! generate {
26 ($(
27 $(#[$doc:meta])*
28 ($Select:ident, <$($Fut:ident),*>),
29 )*) => ($(
30 paste::item! {
31 pub(crate) struct $Select<$($Fut: Future + Unpin),*> {
32 $($Fut: MaybeDone<$Fut>,)*
33 }
34 }
35
36 impl<$($Fut: Future + Unpin),*> $Select<$($Fut),*> {
37 paste::item! {
38 pub(crate) fn new($($Fut: $Fut),*) -> $Select<$($Fut),*> {
39 $Select {
40 $($Fut: maybe_done($Fut),)*
41 }
42 }
43 }
44 }
45
46 impl<$($Fut: Future + Unpin),*> Future for $Select<$($Fut),*> {
47 type Output = ($(SelectResult<$Fut>),*);
48
49 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
50 let mut complete = false;
51 $(
52 let $Fut = Pin::new(&mut self.$Fut);
53 complete |= self.$Fut.poll_unpin(cx).is_ready();
56 )*
57
58 if complete {
59 Poll::Ready(($(
60 match std::mem::replace(&mut self.$Fut, MaybeDone::Gone) {
61 MaybeDone::Future(f) => SelectResult::Pending(f),
62 MaybeDone::Done(o) => SelectResult::Finished(o),
63 MaybeDone::Gone => unreachable!(),
64 }
65 ), *))
66 } else {
67 Poll::Pending
68 }
69 }
70 }
71 )*)
72}
73
74generate! {
75 (Select2, <_Fut1, _Fut2>),
77
78 (Select3, <_Fut1, _Fut2, _Fut3>),
80
81 (Select4, <_Fut1, _Fut2, _Fut3, _Fut4>),
83
84 (Select5, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5>),
86
87 (Select6, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5, _Fut6>),
89
90 (Select7, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5, _Fut6, _Fut7>),
92
93 (Select8, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5, _Fut6, _Fut7, _Fut8>),
95
96 (Select9, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5, _Fut6, _Fut7, _Fut8, _Fut9>),
98
99 (Select10, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5, _Fut6, _Fut7, _Fut8, _Fut9, _Fut10>),
101
102 (Select11, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5, _Fut6, _Fut7, _Fut8, _Fut9, _Fut10, _Fut11>),
104
105 (Select12, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5, _Fut6, _Fut7, _Fut8, _Fut9, _Fut10, _Fut11, _Fut12>),
107}