Skip to content

Commit 1b620f9

Browse files
committed
finish up Body <-> JSON conversions
1 parent 8666bb5 commit 1b620f9

File tree

4 files changed

+67
-8
lines changed

4 files changed

+67
-8
lines changed

src/body.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl Body {
167167
/// # Examples
168168
///
169169
/// ```
170-
/// use http_types::{Body, serde::json};
170+
/// use http_types::{Body, convert::json};
171171
///
172172
/// let body = Body::from_json(json!({ "name": "Chashu" }));
173173
/// # drop(body);
@@ -250,7 +250,7 @@ impl Body {
250250
/// ```
251251
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
252252
/// use http_types::Body;
253-
/// use http_types::serde::{Serialize, Deserialize};
253+
/// use http_types::convert::{Serialize, Deserialize};
254254
///
255255
/// #[derive(Debug, Serialize, Deserialize)]
256256
/// struct Cat { name: String }

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ mod hyperium_http;
173173
#[doc(inline)]
174174
pub use crate::type_map::TypeMap;
175175

176-
/// Generic serialization and deserialization.
177-
pub mod serde {
176+
/// Traits for conversions between types.
177+
pub mod convert {
178178
pub use serde::{de::DeserializeOwned, Deserialize, Serialize};
179179
#[doc(inline)]
180180
pub use serde_json::json;

src/request.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::mem;
66
use std::pin::Pin;
77
use std::task::{Context, Poll};
88

9+
use crate::convert::DeserializeOwned;
910
use crate::headers::{
1011
self, HeaderName, HeaderValue, HeaderValues, Headers, Names, ToHeaderValues, Values,
1112
CONTENT_TYPE,
@@ -251,6 +252,35 @@ impl Request {
251252
self.body.into_bytes().await
252253
}
253254

255+
/// Read the body as JSON.
256+
///
257+
/// This consumes the request. If you want to read the body without
258+
/// consuming the request, consider using the `take_body` method and
259+
/// then calling `Body::into_json` or using the Request's AsyncRead
260+
/// implementation to read the body.
261+
///
262+
/// # Examples
263+
///
264+
/// ```
265+
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
266+
/// use http_types::{Body, Url, Method, Request};
267+
/// use http_types::convert::{Serialize, Deserialize};
268+
///
269+
/// #[derive(Debug, Serialize, Deserialize)]
270+
/// struct Cat { name: String }
271+
///
272+
/// let cat = Cat { name: String::from("chashu") };
273+
/// let mut req = Request::new(Method::Get, Url::parse("https://example.com").unwrap());
274+
/// req.set_body(Body::from_json(cat)?);
275+
///
276+
/// let cat: Cat = req.body_json().await?;
277+
/// assert_eq!(&cat.name, "chashu");
278+
/// # Ok(()) }) }
279+
/// ```
280+
pub async fn body_json<T: DeserializeOwned>(self) -> crate::Result<T> {
281+
self.body.into_json().await
282+
}
283+
254284
/// Get an HTTP header.
255285
pub fn header(&self, name: &HeaderName) -> Option<&HeaderValues> {
256286
self.headers.get(name)

src/response.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::mem;
66
use std::pin::Pin;
77
use std::task::{Context, Poll};
88

9+
use crate::convert::DeserializeOwned;
910
use crate::headers::{
1011
self, HeaderName, HeaderValue, HeaderValues, Headers, Names, ToHeaderValues, Values,
1112
CONTENT_TYPE,
@@ -244,11 +245,11 @@ impl Response {
244245
/// use http_types::{Body, Url, Method, Response, StatusCode};
245246
/// use async_std::io::Cursor;
246247
///
247-
/// let mut resp = Response::new(StatusCode::Ok);
248+
/// let mut res = Response::new(StatusCode::Ok);
248249
/// let cursor = Cursor::new("Hello Nori");
249250
/// let body = Body::from_reader(cursor, None);
250-
/// resp.set_body(body);
251-
/// assert_eq!(&resp.body_string().await.unwrap(), "Hello Nori");
251+
/// res.set_body(body);
252+
/// assert_eq!(&res.body_string().await.unwrap(), "Hello Nori");
252253
/// # Ok(()) }) }
253254
/// ```
254255
pub async fn body_string(self) -> io::Result<String> {
@@ -266,7 +267,6 @@ impl Response {
266267
///
267268
/// ```
268269
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
269-
///
270270
/// use http_types::{Body, Url, Method, Response, StatusCode};
271271
///
272272
/// let bytes = vec![1, 2, 3];
@@ -281,6 +281,35 @@ impl Response {
281281
self.body.into_bytes().await
282282
}
283283

284+
/// Read the body as JSON.
285+
///
286+
/// This consumes the response. If you want to read the body without
287+
/// consuming the request, consider using the `take_body` method and
288+
/// then calling `Body::into_json` or using the Response's AsyncRead
289+
/// implementation to read the body.
290+
///
291+
/// # Examples
292+
///
293+
/// ```
294+
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
295+
/// use http_types::{Body, Url, Method, Response, StatusCode};
296+
/// use http_types::convert::{Serialize, Deserialize};
297+
///
298+
/// #[derive(Debug, Serialize, Deserialize)]
299+
/// struct Cat { name: String }
300+
///
301+
/// let cat = Cat { name: String::from("chashu") };
302+
/// let mut res = Response::new(StatusCode::Ok);
303+
/// res.set_body(Body::from_json(cat)?);
304+
///
305+
/// let cat: Cat = res.body_json().await?;
306+
/// assert_eq!(&cat.name, "chashu");
307+
/// # Ok(()) }) }
308+
/// ```
309+
pub async fn body_json<T: DeserializeOwned>(self) -> crate::Result<T> {
310+
self.body.into_json().await
311+
}
312+
284313
/// Set the response MIME.
285314
pub fn set_content_type(&mut self, mime: Mime) -> Option<HeaderValues> {
286315
let value: HeaderValue = mime.into();

0 commit comments

Comments
 (0)