use core::pin::Pin; use core::task::{Context, Poll}; use futures::ready; use futures::stream::*; use hyper::body::{Bytes, HttpBody}; use garage_util::error::Error; pub type BodyType = Box + Send + Unpin>; type StreamType = Pin> + Send>>; pub struct StreamBody { stream: StreamType, } impl StreamBody { pub fn new(stream: StreamType) -> Self { Self { stream } } } impl HttpBody for StreamBody { type Data = Bytes; type Error = Error; fn poll_data( mut self: Pin<&mut Self>, cx: &mut Context, ) -> Poll>> { match ready!(self.stream.as_mut().poll_next(cx)) { Some(res) => Poll::Ready(Some(res)), None => Poll::Ready(None), } } fn poll_trailers( self: Pin<&mut Self>, _cx: &mut Context, ) -> Poll>, Self::Error>> { Poll::Ready(Ok(None)) } } pub struct BytesBody { bytes: Option, } impl BytesBody { pub fn new(bytes: Bytes) -> Self { Self { bytes: Some(bytes) } } } impl HttpBody for BytesBody { type Data = Bytes; type Error = Error; fn poll_data( mut self: Pin<&mut Self>, _cx: &mut Context, ) -> Poll>> { Poll::Ready(self.bytes.take().map(Ok)) } fn poll_trailers( self: Pin<&mut Self>, _cx: &mut Context, ) -> Poll>, Self::Error>> { Poll::Ready(Ok(None)) } } impl From for BytesBody { fn from(x: String) -> BytesBody { Self::new(Bytes::from(x)) } } impl From> for BytesBody { fn from(x: Vec) -> BytesBody { Self::new(Bytes::from(x)) } } pub fn empty_body() -> BodyType { Box::new(BytesBody::from(vec![])) }