use std::{
pin::Pin,
task::{Context, Poll},
};
use futures_core::Stream;
use futures_sink::Sink;
use futures_util::SinkExt;
use crate::{backend::*, task::Task, worker::context::WorkerContext};
#[derive(Debug, Clone)]
pub struct Interleave<B, S> {
pub(super) backend: B,
pub(super) stream: S,
pub(super) stream_done: bool,
}
impl<B, S> Interleave<B, S> {
pub fn new(backend: B, stream: S) -> Self {
Self {
backend,
stream,
stream_done: false,
}
}
}
impl<B, S> Backend for Interleave<B, S>
where
B: Backend,
S: Stream<Item = Result<B::Task, B::Error>> + Unpin,
{
type Task = B::Task;
type Error = B::Error;
fn poll_ready(
&mut self,
cx: &mut Context<'_>,
worker: &WorkerContext,
) -> Poll<Result<(), Self::Error>> {
self.backend.poll_ready(cx, worker)
}
fn poll_next(
&mut self,
cx: &mut Context<'_>,
worker: &WorkerContext,
) -> Poll<Option<Result<Self::Task, Self::Error>>> {
if !self.stream_done {
match Pin::new(&mut self.stream).poll_next(cx) {
Poll::Ready(Some(item)) => return Poll::Ready(Some(item)),
Poll::Ready(None) => {
self.stream_done = true;
}
Poll::Pending => {}
}
}
self.backend.poll_next(cx, worker)
}
fn poll_close(
&mut self,
cx: &mut Context<'_>,
worker: &WorkerContext,
) -> Poll<Result<(), Self::Error>> {
self.backend.poll_close(cx, worker)
}
}
delegate_sink!(Interleave<B, S>, backend);
delegate_deref!(Interleave<B, S>, backend);
delegate_config!(Interleave<B, S>, backend);
delegate_codec!(Interleave<B, S>, backend);
delegate_expose!(
impl<B, S> for Interleave<B, S>
where {
B: Send + Sync,
S: Stream<Item = Result<B::Task, B::Error>> + Send + Sync + Unpin,
}
=> backend
);