use futures_lite::prelude::*;
use futures_lite::stream::Fuse;
use std::pin::Pin;
use std::task::{Context, Poll};
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[derive(Debug)]
pub(crate) struct Merge<L, R> {
left: Pin<Box<Fuse<L>>>,
right: Pin<Box<Fuse<R>>>,
alt: bool,
}
impl<L: Stream, R: Stream> Merge<L, R> {
pub(crate) fn new(left: L, right: R) -> Self {
Self {
left: Box::pin(left.fuse()),
right: Box::pin(right.fuse()),
alt: false,
}
}
}
impl<L, R, T> Stream for Merge<L, R>
where
L: Stream<Item = T>,
R: Stream<Item = T>,
{
type Item = T;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.alt = !self.alt;
if self.alt {
match self.left.as_mut().poll_next(cx) {
Poll::Ready(None) => self.right.as_mut().poll_next(cx),
Poll::Ready(item) => Poll::Ready(item),
Poll::Pending => match self.right.as_mut().poll_next(cx) {
Poll::Ready(None) | Poll::Pending => Poll::Pending,
Poll::Ready(item) => Poll::Ready(item),
},
}
} else {
match self.right.as_mut().poll_next(cx) {
Poll::Ready(None) => self.left.as_mut().poll_next(cx),
Poll::Ready(item) => Poll::Ready(item),
Poll::Pending => match self.left.as_mut().poll_next(cx) {
Poll::Ready(None) | Poll::Pending => Poll::Pending,
Poll::Ready(item) => Poll::Ready(item),
},
}
}
}
}