#[macro_export]
macro_rules! impl_one_of (
($enum_name:ident ; $head_variant:ident, $($tail_variants:ident),*) => {
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum $enum_name<$head_variant, $( $tail_variants ),*> {
$head_variant($head_variant),
$( $tail_variants($tail_variants) ),*
}
impl<$head_variant, $($tail_variants),*> ::core::future::Future for
$enum_name<$head_variant, $($tail_variants ),*>
where
$head_variant: ::core::future::Future,
$( $tail_variants: ::core::future::Future<Output=$head_variant::Output> ),* {
type Output = $head_variant::Output;
fn poll(self: ::core::pin::Pin<&mut Self>, cx: &mut ::core::task::Context<'_>) ->::core::task::Poll<Self::Output> {
unsafe {
match self.get_unchecked_mut() {
$enum_name::$head_variant(x) => ::core::pin::Pin::new_unchecked(x).poll(cx),
$(
$enum_name::$tail_variants(x) => ::core::pin::Pin::new_unchecked(x).poll(cx),
)*
}
}
}
}
impl<$head_variant, $($tail_variants),*> $crate::FusedFuture for
$enum_name<$head_variant, $($tail_variants ),*>
where
$head_variant: $crate::FusedFuture,
$( $tail_variants: $crate::FusedFuture<Output=$head_variant::Output> ),* {
fn is_terminated(&self) -> bool {
match self {
$enum_name::$head_variant(x) => x.is_terminated(),
$(
$enum_name::$tail_variants(x) => x.is_terminated(),
)*
}
}
}
impl<$head_variant, $($tail_variants),*> $crate::Stream for
$enum_name<$head_variant, $($tail_variants ),*>
where
$head_variant: $crate::Stream,
$( $tail_variants: $crate::Stream<Item=$head_variant::Item> ),* {
type Item = $head_variant::Item;
fn poll_next(self: ::core::pin::Pin<&mut Self>, cx: &mut ::core::task::Context<'_>) ->::core::task::Poll<Option<$head_variant::Item>> {
unsafe {
match self.get_unchecked_mut() {
$enum_name::$head_variant(x) => ::core::pin::Pin::new_unchecked(x).poll_next(cx),
$(
$enum_name::$tail_variants(x) => ::core::pin::Pin::new_unchecked(x).poll_next(cx),
)*
}
}
}
}
impl<$head_variant, $($tail_variants),*> $crate::FusedStream for
$enum_name<$head_variant, $( $tail_variants ),*>
where
$head_variant: $crate::FusedStream,
$( $tail_variants: $crate::FusedStream<Item=$head_variant::Item> ),* {
fn is_terminated(&self) -> bool {
match self {
$enum_name::$head_variant(x) => x.is_terminated(),
$(
$enum_name::$tail_variants(x) => x.is_terminated(),
)*
}
}
}
#[cfg(feature = "sink")]
impl<Item, $head_variant, $($tail_variants),*> futures_sink::Sink<Item> for
$enum_name<$head_variant, $( $tail_variants ),*>
where
$head_variant: futures_sink::Sink<Item>,
$( $tail_variants: futures_sink::Sink<Item, Error=$head_variant::Error> ),* {
type Error = $head_variant::Error;
fn poll_ready(self: ::core::pin::Pin<&mut Self>, cx: &mut ::core::task::Context<'_>) ->::core::task::Poll<Result<(), Self::Error>> {
unsafe {
match self.get_unchecked_mut() {
$enum_name::$head_variant(x) => ::core::pin::Pin::new_unchecked(x).poll_ready(cx),
$(
$enum_name::$tail_variants(x) => ::core::pin::Pin::new_unchecked(x).poll_ready(cx),
)*
}
}
}
fn start_send(self: ::core::pin::Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
unsafe {
match self.get_unchecked_mut() {
$enum_name::$head_variant(x) => ::core::pin::Pin::new_unchecked(x).start_send(item),
$(
$enum_name::$tail_variants(x) => ::core::pin::Pin::new_unchecked(x).start_send(item),
)*
}
}
}
fn poll_flush(self: ::core::pin::Pin<&mut Self>, cx: &mut ::core::task::Context<'_>) ->::core::task::Poll<Result<(), Self::Error>> {
unsafe {
match self.get_unchecked_mut() {
$enum_name::$head_variant(x) => ::core::pin::Pin::new_unchecked(x).poll_flush(cx),
$(
$enum_name::$tail_variants(x) => ::core::pin::Pin::new_unchecked(x).poll_flush(cx),
)*
}
}
}
fn poll_close(self: ::core::pin::Pin<&mut Self>, cx: &mut ::core::task::Context<'_>) ->::core::task::Poll<Result<(), Self::Error>> {
unsafe {
match self.get_unchecked_mut() {
$enum_name::$head_variant(x) => ::core::pin::Pin::new_unchecked(x).poll_close(cx),
$(
$enum_name::$tail_variants(x) => ::core::pin::Pin::new_unchecked(x).poll_close(cx),
)*
}
}
}
}
}
);
impl_one_of!(OneOf8; One, Two, Three, Four, Five, Six, Seven, Eight);
impl_one_of!(OneOf7; One, Two, Three, Four, Five, Six, Seven);
impl_one_of!(OneOf6; One, Two, Three, Four, Five, Six);
impl_one_of!(OneOf5; One, Two, Three, Four, Five);
impl_one_of!(OneOf4; One, Two, Three, Four);
impl_one_of!(OneOf3; One, Two, Three);
impl_one_of!(OneOf2; One, Two);