http_body_reader/
body_reader.rs1use std::string::FromUtf8Error;
2
3use bytes::{Buf, Bytes};
4use http::HeaderMap;
5use http_body::Body;
6use http_body_util::BodyExt;
7use thiserror::Error;
8
9#[derive(Debug, Clone)]
13pub struct BodyReader<B> {
14 body: B,
15 #[allow(dead_code)]
16 headers: HeaderMap,
17}
18
19#[derive(Debug, Error)]
21#[error(transparent)]
22pub enum BodyReaderError<E, D> {
23 Read(E),
25 Decode(D),
27}
28
29impl<B> BodyReader<B> {
30 #[doc = include_str!("../examples/read_bytes.rs")]
36 pub async fn bytes(self) -> Result<Bytes, B::Error>
38 where
39 B: Body,
40 B::Data: Buf,
41 {
42 let body_bytes = self.body.collect().await?.to_bytes();
43 Ok(body_bytes)
44 }
45
46 #[doc = include_str!("../examples/read_utf8.rs")]
61 pub async fn utf8(self) -> Result<String, BodyReaderError<B::Error, FromUtf8Error>>
63 where
64 B: Body,
65 B::Data: Buf,
66 {
67 let bytes = self.bytes().await.map_err(BodyReaderError::Read)?;
68 String::from_utf8(bytes.into()).map_err(BodyReaderError::Decode)
69 }
70
71 #[doc = include_str!("../examples/read_json.rs")]
82 #[cfg(feature = "json")]
84 #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
85 pub async fn json<T>(self) -> Result<T, BodyReaderError<B::Error, serde_json::Error>>
86 where
87 T: serde::de::DeserializeOwned,
88 B: Body,
89 B::Data: Buf,
90 {
91 let bytes = self.bytes().await.map_err(BodyReaderError::Read)?;
92 serde_json::from_slice(&bytes).map_err(BodyReaderError::Decode)
93 }
94
95 #[doc = include_str!("../examples/read_form.rs")]
106 #[cfg(feature = "form")]
108 #[cfg_attr(docsrs, doc(cfg(feature = "form")))]
109 pub async fn form<T>(self) -> Result<T, BodyReaderError<B::Error, serde_urlencoded::de::Error>>
110 where
111 T: serde::de::DeserializeOwned,
112 B: Body,
113 B::Data: Buf,
114 {
115 let bytes = self.bytes().await.map_err(BodyReaderError::Read)?;
116 serde_urlencoded::from_bytes(&bytes).map_err(BodyReaderError::Decode)
117 }
118
119 #[doc = include_str!("../examples/map_body.rs")]
125 pub fn map<F, T>(self, f: F) -> BodyReader<T>
127 where
128 F: FnOnce(B) -> T,
129 T: Body,
130 T::Data: Buf,
131 {
132 BodyReader {
133 body: f(self.body),
134 headers: self.headers,
135 }
136 }
137}
138
139impl<B> From<http::Response<B>> for BodyReader<B> {
140 fn from(response: http::Response<B>) -> Self {
141 let (parts, body) = response.into_parts();
142 Self {
143 body,
144 headers: parts.headers,
145 }
146 }
147}