1use std::pin::Pin;
2use std::task::{Context, Poll};
3
4use bytes::Buf;
5use bytes::Bytes;
6use futures_util::StreamExt;
7use http_body::Frame;
8use http_body_util::{combinators::BoxBody, BodyExt};
9
10#[derive(Debug)]
11pub struct Body(BoxBody<Bytes, crate::Error>);
12
13impl Default for Body {
14 fn default() -> Self {
15 Body::empty()
16 }
17}
18
19impl http_body::Body for Body {
20 type Data = Bytes;
21 type Error = crate::Error;
22
23 fn poll_frame(
24 mut self: Pin<&mut Self>,
25 cx: &mut Context<'_>,
26 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
27 Pin::new(&mut self.0).poll_frame(cx)
28 }
29
30 fn is_end_stream(&self) -> bool {
31 self.0.is_end_stream()
32 }
33
34 fn size_hint(&self) -> http_body::SizeHint {
35 self.0.size_hint()
36 }
37}
38
39impl Body {
40 pub(crate) fn empty() -> Self {
41 Body(
42 http_body_util::Empty::<Bytes>::new()
43 .map_err(crate::Error::new)
44 .boxed(),
45 )
46 }
47
48 pub(crate) fn wrap<B>(body: B) -> Self
49 where
50 B: http_body::Body + Send + Sync + 'static,
51 B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
52 {
53 let body = body
54 .map_frame(|f| f.map_data(|mut buf| buf.copy_to_bytes(buf.remaining())))
55 .map_err(crate::Error::new);
56 Body(http_body_util::BodyExt::boxed(body))
57 }
58
59 pub(crate) fn wrap_stream<S, B, E>(stream: S) -> Self
60 where
61 S: futures_util::Stream<Item = Result<B, E>> + Send + Sync + 'static,
62 B: Into<Bytes>,
63 E: Into<Box<dyn std::error::Error + Send + Sync>> + Send + 'static,
64 {
65 let body = http_body_util::StreamBody::new(stream.map(|item| {
66 item.map(|buf| Frame::data(buf.into()))
67 .map_err(crate::Error::new)
68 }));
69 Body(http_body_util::BodyExt::boxed(body))
70 }
71}
72
73impl From<Bytes> for Body {
74 fn from(b: Bytes) -> Self {
75 Body(
76 http_body_util::Full::new(b)
77 .map_err(crate::Error::new)
78 .boxed(),
79 )
80 }
81}
82
83impl From<&'static str> for Body {
84 fn from(s: &'static str) -> Self {
85 Bytes::from(s).into()
86 }
87}
88
89impl From<String> for Body {
90 fn from(s: String) -> Self {
91 Bytes::from(s).into()
92 }
93}
94
95impl From<&'static [u8]> for Body {
96 fn from(v: &'static [u8]) -> Self {
97 Bytes::from(v).into()
98 }
99}
100
101impl From<Vec<u8>> for Body {
102 fn from(v: Vec<u8>) -> Self {
103 Bytes::from(v).into()
104 }
105}
106
107impl From<Option<Bytes>> for Body {
108 fn from(opt: Option<Bytes>) -> Self {
109 match opt {
110 Some(b) => b.into(),
111 None => Body::empty(),
112 }
113 }
114}