Skip to main content

tower_embed_core/
http.rs

1//! HTTP body types for requests and responses.
2
3use std::{
4    pin::Pin,
5    task::{Context, Poll},
6};
7
8use bytes::Bytes;
9use futures_core::Stream;
10use http_body_util::BodyExt;
11
12use crate::BoxError;
13
14/// The body used in responses.
15#[derive(Debug)]
16pub struct Body(BodyInner);
17
18type BodyInner = http_body_util::combinators::UnsyncBoxBody<Bytes, BoxError>;
19
20impl Body {
21    /// Create an empty response body.
22    pub fn empty() -> Self {
23        Body::new(http_body_util::Empty::new())
24    }
25
26    /// Create a new response body that contains a single chunk
27    pub fn full(data: Bytes) -> Self {
28        Body::new(http_body_util::Full::new(data))
29    }
30
31    /// Create a response body from a stream of bytes.
32    pub fn stream<S, E>(stream: S) -> Self
33    where
34        S: Stream<Item = Result<http_body::Frame<Bytes>, E>> + Send + 'static,
35        E: Into<BoxError>,
36    {
37        Body::new(http_body_util::StreamBody::new(stream))
38    }
39
40    fn new<B>(body: B) -> Self
41    where
42        B: http_body::Body<Data = Bytes> + Send + 'static,
43        B::Error: Into<BoxError>,
44    {
45        Body(body.map_err(|err| err.into()).boxed_unsync())
46    }
47}
48
49impl http_body::Body for Body {
50    type Data = Bytes;
51    type Error = BoxError;
52
53    fn poll_frame(
54        mut self: Pin<&mut Self>,
55        cx: &mut Context<'_>,
56    ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> {
57        Pin::new(&mut self.0).poll_frame(cx)
58    }
59
60    fn is_end_stream(&self) -> bool {
61        self.0.is_end_stream()
62    }
63
64    fn size_hint(&self) -> http_body::SizeHint {
65        self.0.size_hint()
66    }
67}