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