1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker // Need non-snake case so the macro can re-use type names for variables. 6*bb4ee6a4SAndroid Build Coastguard Worker #![allow(non_snake_case)] 7*bb4ee6a4SAndroid Build Coastguard Worker 8*bb4ee6a4SAndroid Build Coastguard Worker use std::future::Future; 9*bb4ee6a4SAndroid Build Coastguard Worker use std::pin::Pin; 10*bb4ee6a4SAndroid Build Coastguard Worker use std::task::Context; 11*bb4ee6a4SAndroid Build Coastguard Worker use std::task::Poll; 12*bb4ee6a4SAndroid Build Coastguard Worker 13*bb4ee6a4SAndroid Build Coastguard Worker use futures::future::maybe_done; 14*bb4ee6a4SAndroid Build Coastguard Worker use futures::future::MaybeDone; 15*bb4ee6a4SAndroid Build Coastguard Worker use pin_utils::unsafe_pinned; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker // Macro-generate future combinators to allow for running different numbers of top-level futures in 18*bb4ee6a4SAndroid Build Coastguard Worker // this FutureList. Generates the implementation of `FutureList` for the completion types. For an 19*bb4ee6a4SAndroid Build Coastguard Worker // explicit example this is modeled after, see `UnitFutures`. 20*bb4ee6a4SAndroid Build Coastguard Worker macro_rules! generate { 21*bb4ee6a4SAndroid Build Coastguard Worker ($( 22*bb4ee6a4SAndroid Build Coastguard Worker $(#[$doc:meta])* 23*bb4ee6a4SAndroid Build Coastguard Worker ($Complete:ident, <$($Fut:ident),*>), 24*bb4ee6a4SAndroid Build Coastguard Worker )*) => ($( 25*bb4ee6a4SAndroid Build Coastguard Worker #[must_use = "Combinations of futures don't do anything unless run in an executor."] 26*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) struct $Complete<$($Fut: Future),*> { 27*bb4ee6a4SAndroid Build Coastguard Worker $($Fut: MaybeDone<$Fut>,)* 28*bb4ee6a4SAndroid Build Coastguard Worker } 29*bb4ee6a4SAndroid Build Coastguard Worker 30*bb4ee6a4SAndroid Build Coastguard Worker impl<$($Fut),*> $Complete<$($Fut),*> 31*bb4ee6a4SAndroid Build Coastguard Worker where $( 32*bb4ee6a4SAndroid Build Coastguard Worker $Fut: Future, 33*bb4ee6a4SAndroid Build Coastguard Worker )* 34*bb4ee6a4SAndroid Build Coastguard Worker { 35*bb4ee6a4SAndroid Build Coastguard Worker // Safety: 36*bb4ee6a4SAndroid Build Coastguard Worker // * No Drop impl 37*bb4ee6a4SAndroid Build Coastguard Worker // * No Unpin impl 38*bb4ee6a4SAndroid Build Coastguard Worker // * Not #[repr(packed)] 39*bb4ee6a4SAndroid Build Coastguard Worker $( 40*bb4ee6a4SAndroid Build Coastguard Worker unsafe_pinned!($Fut: MaybeDone<$Fut>); 41*bb4ee6a4SAndroid Build Coastguard Worker )* 42*bb4ee6a4SAndroid Build Coastguard Worker 43*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) fn new($($Fut: $Fut),*) -> $Complete<$($Fut),*> { 44*bb4ee6a4SAndroid Build Coastguard Worker $( 45*bb4ee6a4SAndroid Build Coastguard Worker let $Fut = maybe_done($Fut); 46*bb4ee6a4SAndroid Build Coastguard Worker )* 47*bb4ee6a4SAndroid Build Coastguard Worker $Complete { 48*bb4ee6a4SAndroid Build Coastguard Worker $($Fut),* 49*bb4ee6a4SAndroid Build Coastguard Worker } 50*bb4ee6a4SAndroid Build Coastguard Worker } 51*bb4ee6a4SAndroid Build Coastguard Worker } 52*bb4ee6a4SAndroid Build Coastguard Worker 53*bb4ee6a4SAndroid Build Coastguard Worker impl<$($Fut),*> Future for $Complete<$($Fut),*> 54*bb4ee6a4SAndroid Build Coastguard Worker where $( 55*bb4ee6a4SAndroid Build Coastguard Worker $Fut: Future, 56*bb4ee6a4SAndroid Build Coastguard Worker )* 57*bb4ee6a4SAndroid Build Coastguard Worker { 58*bb4ee6a4SAndroid Build Coastguard Worker type Output = ($($Fut::Output),*); 59*bb4ee6a4SAndroid Build Coastguard Worker 60*bb4ee6a4SAndroid Build Coastguard Worker fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { 61*bb4ee6a4SAndroid Build Coastguard Worker let mut complete = true; 62*bb4ee6a4SAndroid Build Coastguard Worker $( 63*bb4ee6a4SAndroid Build Coastguard Worker complete &= self.as_mut().$Fut().poll(cx).is_ready(); 64*bb4ee6a4SAndroid Build Coastguard Worker )* 65*bb4ee6a4SAndroid Build Coastguard Worker 66*bb4ee6a4SAndroid Build Coastguard Worker if complete { 67*bb4ee6a4SAndroid Build Coastguard Worker $( 68*bb4ee6a4SAndroid Build Coastguard Worker let $Fut = self.as_mut().$Fut().take_output().unwrap(); 69*bb4ee6a4SAndroid Build Coastguard Worker )* 70*bb4ee6a4SAndroid Build Coastguard Worker Poll::Ready(($($Fut), *)) 71*bb4ee6a4SAndroid Build Coastguard Worker } else { 72*bb4ee6a4SAndroid Build Coastguard Worker Poll::Pending 73*bb4ee6a4SAndroid Build Coastguard Worker } 74*bb4ee6a4SAndroid Build Coastguard Worker } 75*bb4ee6a4SAndroid Build Coastguard Worker } 76*bb4ee6a4SAndroid Build Coastguard Worker )*) 77*bb4ee6a4SAndroid Build Coastguard Worker } 78*bb4ee6a4SAndroid Build Coastguard Worker 79*bb4ee6a4SAndroid Build Coastguard Worker generate! { 80*bb4ee6a4SAndroid Build Coastguard Worker /// _Future for the [`complete2`] function. 81*bb4ee6a4SAndroid Build Coastguard Worker (Complete2, <_Fut1, _Fut2>), 82*bb4ee6a4SAndroid Build Coastguard Worker 83*bb4ee6a4SAndroid Build Coastguard Worker /// _Future for the [`complete3`] function. 84*bb4ee6a4SAndroid Build Coastguard Worker (Complete3, <_Fut1, _Fut2, _Fut3>), 85*bb4ee6a4SAndroid Build Coastguard Worker 86*bb4ee6a4SAndroid Build Coastguard Worker /// _Future for the [`complete4`] function. 87*bb4ee6a4SAndroid Build Coastguard Worker (Complete4, <_Fut1, _Fut2, _Fut3, _Fut4>), 88*bb4ee6a4SAndroid Build Coastguard Worker 89*bb4ee6a4SAndroid Build Coastguard Worker /// _Future for the [`complete5`] function. 90*bb4ee6a4SAndroid Build Coastguard Worker (Complete5, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5>), 91*bb4ee6a4SAndroid Build Coastguard Worker } 92