Skip to content

Commit 8666bb5

Browse files
committed
Body::{from,into}_json
1 parent b9129e4 commit 8666bb5

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ unstable = []
2222
hyperium_http = ["http"]
2323

2424
[dependencies]
25-
2625
# Note(yoshuawuyts): used for async_std's `channel` only; use "core" once possible.
2726
async-std = { version = "1.4.0", features = ["unstable"] }
2827

@@ -36,7 +35,7 @@ omnom = "2.1.1"
3635
pin-project-lite = "0.1.0"
3736
url = "2.1.0"
3837
serde_json = "1.0.51"
39-
serde = { version = "1.0", features = ["derive"] }
38+
serde = { version = "1.0.106", features = ["derive"] }
4039

4140
[dev-dependencies]
4241
http = "0.2.0"

src/body.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use async_std::io::prelude::*;
2-
use async_std::io::{self, BufRead, Read};
2+
use async_std::io::{self, Cursor};
3+
use serde::{de::DeserializeOwned, Serialize};
34

45
use std::fmt::{self, Debug};
56
use std::pin::Pin;
@@ -157,6 +158,30 @@ impl Body {
157158
Ok(buf)
158159
}
159160

161+
/// Creates a `Body` from a type, serializing it as JSON.
162+
///
163+
/// # Mime
164+
///
165+
/// The encoding is set to `application/json`.
166+
///
167+
/// # Examples
168+
///
169+
/// ```
170+
/// use http_types::{Body, serde::json};
171+
///
172+
/// let body = Body::from_json(json!({ "name": "Chashu" }));
173+
/// # drop(body);
174+
/// ```
175+
pub fn from_json(json: impl Serialize) -> crate::Result<Self> {
176+
let bytes = serde_json::to_vec(&json)?;
177+
let body = Self {
178+
length: Some(bytes.len()),
179+
reader: Box::new(Cursor::new(bytes)),
180+
mime: mime::JSON,
181+
};
182+
Ok(body)
183+
}
184+
160185
/// Get the length of the body in bytes.
161186
///
162187
/// # Examples
@@ -218,6 +243,31 @@ impl Body {
218243
Ok(result)
219244
}
220245

246+
/// Parse the body as JSON, serializing it to a struct.
247+
///
248+
/// # Examples
249+
///
250+
/// ```
251+
/// # fn main() -> Result<(), http_types::Error> { async_std::task::block_on(async {
252+
/// use http_types::Body;
253+
/// use http_types::serde::{Serialize, Deserialize};
254+
///
255+
/// #[derive(Debug, Serialize, Deserialize)]
256+
/// struct Cat { name: String }
257+
///
258+
/// let cat = Cat { name: String::from("chashu") };
259+
/// let body = Body::from_json(cat)?;
260+
///
261+
/// let cat: Cat = body.into_json().await?;
262+
/// assert_eq!(&cat.name, "chashu");
263+
/// # Ok(()) }) }
264+
/// ```
265+
pub async fn into_json<T: DeserializeOwned>(mut self) -> crate::Result<T> {
266+
let mut buf = Vec::with_capacity(1024);
267+
self.read_to_end(&mut buf).await?;
268+
Ok(serde_json::from_slice(&buf).map_err(io::Error::from)?)
269+
}
270+
221271
pub(crate) fn mime(&self) -> &Mime {
222272
&self.mime
223273
}
@@ -236,7 +286,7 @@ impl From<String> for Body {
236286
fn from(s: String) -> Self {
237287
Self {
238288
length: Some(s.len()),
239-
reader: Box::new(io::Cursor::new(s.into_bytes())),
289+
reader: Box::new(Cursor::new(s.into_bytes())),
240290
mime: mime::PLAIN,
241291
}
242292
}
@@ -246,7 +296,7 @@ impl<'a> From<&'a str> for Body {
246296
fn from(s: &'a str) -> Self {
247297
Self {
248298
length: Some(s.len()),
249-
reader: Box::new(io::Cursor::new(s.to_owned().into_bytes())),
299+
reader: Box::new(Cursor::new(s.to_owned().into_bytes())),
250300
mime: mime::PLAIN,
251301
}
252302
}
@@ -256,7 +306,7 @@ impl From<Vec<u8>> for Body {
256306
fn from(b: Vec<u8>) -> Self {
257307
Self {
258308
length: Some(b.len()),
259-
reader: Box::new(io::Cursor::new(b)),
309+
reader: Box::new(Cursor::new(b)),
260310
mime: mime::BYTE_STREAM,
261311
}
262312
}

src/lib.rs

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

176+
/// Generic serialization and deserialization.
177+
pub mod serde {
178+
pub use serde::{de::DeserializeOwned, Deserialize, Serialize};
179+
#[doc(inline)]
180+
pub use serde_json::json;
181+
}
182+
176183
// Not public API. Referenced by macro-generated code.
177184
#[doc(hidden)]
178185
pub mod private {

0 commit comments

Comments
 (0)