use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
pub struct AnyOf {
futures: Vec<Pin<Box<dyn Future<Output = ()>>>>,
}
impl std::fmt::Debug for AnyOf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AnyOf")
.field("pending", &self.futures.len())
.finish()
}
}
impl AnyOf {
#[must_use = "futures do nothing unless awaited"]
pub fn new(futures: Vec<Pin<Box<dyn Future<Output = ()>>>>) -> Self {
assert!(!futures.is_empty(), "AnyOf requires at least one future");
AnyOf { futures }
}
}
impl Future for AnyOf {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
for fut in self.get_mut().futures.iter_mut() {
if fut.as_mut().poll(cx).is_ready() {
return Poll::Ready(());
}
}
Poll::Pending
}
}
pub struct AllOf {
futures: Vec<Pin<Box<dyn Future<Output = ()>>>>,
}
impl std::fmt::Debug for AllOf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AllOf")
.field("pending", &self.futures.len())
.finish()
}
}
impl AllOf {
#[must_use = "futures do nothing unless awaited"]
pub fn new(futures: Vec<Pin<Box<dyn Future<Output = ()>>>>) -> Self {
AllOf { futures }
}
}
impl Future for AllOf {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
let this = self.as_mut().get_mut();
this.futures
.retain_mut(|fut| fut.as_mut().poll(cx).is_pending());
if this.futures.is_empty() {
Poll::Ready(())
} else {
Poll::Pending
}
}
}
#[macro_export]
macro_rules! any_of {
($($fut:expr),+ $(,)?) => {
$crate::AnyOf::new(
vec![$(::std::boxed::Box::pin($fut)),+]
)
};
}
#[macro_export]
macro_rules! all_of {
($($fut:expr),+ $(,)?) => {
$crate::AllOf::new(
vec![$(::std::boxed::Box::pin($fut)),+]
)
};
}