use std::pin::Pin; use std::task::{Context, Poll}; use bytes::Bytes; use futures_core::Stream; use h2::RecvStream; use crate::error::PayloadError; // TODO: rename to boxed payload /// A boxed payload. pub type PayloadStream = Pin>>>; /// A streaming payload. pub enum Payload { None, H1(crate::h1::Payload), H2(crate::h2::Payload), Stream(S), } impl From for Payload { fn from(v: crate::h1::Payload) -> Self { Payload::H1(v) } } impl From for Payload { fn from(v: crate::h2::Payload) -> Self { Payload::H2(v) } } impl From for Payload { fn from(v: RecvStream) -> Self { Payload::H2(crate::h2::Payload::new(v)) } } impl From for Payload { fn from(pl: PayloadStream) -> Self { Payload::Stream(pl) } } impl Payload { /// Takes current payload and replaces it with `None` value pub fn take(&mut self) -> Payload { std::mem::replace(self, Payload::None) } } impl Stream for Payload where S: Stream> + Unpin, { type Item = Result; #[inline] fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.get_mut() { Payload::None => Poll::Ready(None), Payload::H1(ref mut pl) => pl.readany(cx), Payload::H2(ref mut pl) => Pin::new(pl).poll_next(cx), Payload::Stream(ref mut pl) => Pin::new(pl).poll_next(cx), } } }