use std::pin::Pin;
use std::task::{Context, Poll};
use bytes::Bytes;
use futures::Stream;
use pin_project_lite::pin_project;
use crate::proto::reliability::{ReliabilityMessage, SharedReliabilityState};
pin_project! {
pub struct ReliabilityStream<T: Stream<Item = Bytes>> {
#[pin]
stream: T,
state: SharedReliabilityState,
buffer: Option<Poll<Option<Bytes>>>,
}
}
impl<T: Stream<Item = Bytes>> ReliabilityStream<T> {
pub fn new(stream: T, state: SharedReliabilityState) -> Self {
Self {
stream,
state,
buffer: None,
}
}
}
impl<T: Stream<Item = Bytes>> Stream for ReliabilityStream<T> {
type Item = ReliabilityMessage;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
let this = self.project();
let next_payload = match this.buffer.take() {
Some(Poll::Ready(result)) => Poll::Ready(result),
_ => this.stream.poll_next(cx),
};
let (result, next_buffer) = this.state.poll_recv(cx, next_payload);
*this.buffer = next_buffer;
result
}
}