Skip to content

Commit e31ce68

Browse files
authored
Merge pull request #334 from jbr/serde-feature
add a serde feature that's enabled by default
2 parents a47a9b1 + f6eb46c commit e31ce68

File tree

11 files changed

+220
-156
lines changed

11 files changed

+220
-156
lines changed

Cargo.toml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,41 @@ features = ["docs"]
1616
rustdoc-args = ["--cfg", "feature=\"docs\""]
1717

1818
[features]
19-
default = ["fs", "cookie-secure"]
19+
default = ["fs", "cookie-secure", "serde"]
2020
docs = ["unstable"]
2121
unstable = []
2222
hyperium_http = ["http"]
2323
async_std = ["fs"]
2424
cookies = ["cookie"]
2525
cookie-secure = ["cookies", "cookie/secure"]
2626
fs = ["async-std"]
27+
serde = ["serde_qs", "serde_crate", "serde_json", "serde_urlencoded", "url/serde"]
2728

2829
[dependencies]
29-
# features: async_std
30-
async-std = { version = "1.6.0", optional = true }
30+
rand = "0.7.3"
31+
base64 = "0.13.0"
3132
futures-lite = "1.11.1"
3233
async-channel = "1.5.1"
34+
infer = "0.2.3"
35+
pin-project-lite = "0.2.0"
36+
url = "2.1.1"
37+
anyhow = "1.0.26"
38+
39+
# features: async_std
40+
async-std = { version = "1.6.0", optional = true }
3341

3442
# features: hyperium/http
3543
http = { version = "0.2.0", optional = true }
3644

37-
anyhow = "1.0.26"
38-
3945
# features: cookies
4046
cookie = { version = "0.14.0", features = ["percent-encode"], optional = true }
41-
infer = "0.2.3"
42-
pin-project-lite = "0.2.0"
43-
url = { version = "2.1.1", features = ["serde"] }
44-
serde_json = "1.0.51"
45-
serde = { version = "1.0.106", features = ["derive"] }
46-
serde_urlencoded = "0.7.0"
47-
rand = "0.7.3"
48-
serde_qs = "0.7.0"
49-
base64 = "0.13.0"
47+
48+
# features: serde
49+
serde_json = { version = "1.0.51", optional = true }
50+
serde_crate = { version = "1.0.106", features = ["derive"], optional = true, package = "serde" }
51+
serde_urlencoded = { version = "0.7.0", optional = true}
52+
serde_qs = { version = "0.7.0", optional = true }
53+
5054

5155
[dev-dependencies]
5256
http = "0.2.0"

src/body.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use futures_lite::{io, prelude::*, ready};
2-
use serde::{de::DeserializeOwned, Serialize};
2+
#[cfg(feature = "serde")]
3+
use serde_crate::{de::DeserializeOwned, Serialize};
34

45
use std::convert::TryFrom;
56
use std::fmt::{self, Debug};
@@ -246,6 +247,7 @@ impl Body {
246247
/// let body = Body::from_json(&json!({ "name": "Chashu" }));
247248
/// # drop(body);
248249
/// ```
250+
#[cfg(feature = "serde")]
249251
pub fn from_json(json: &impl Serialize) -> crate::Result<Self> {
250252
let bytes = serde_json::to_vec(&json)?;
251253
let body = Self {
@@ -267,6 +269,7 @@ impl Body {
267269
/// use http_types::convert::{Serialize, Deserialize};
268270
///
269271
/// #[derive(Debug, Serialize, Deserialize)]
272+
/// # #[serde(crate = "serde_crate")]
270273
/// struct Cat { name: String }
271274
///
272275
/// let cat = Cat { name: String::from("chashu") };
@@ -276,6 +279,7 @@ impl Body {
276279
/// assert_eq!(&cat.name, "chashu");
277280
/// # Ok(()) }) }
278281
/// ```
282+
#[cfg(feature = "serde")]
279283
pub async fn into_json<T: DeserializeOwned>(mut self) -> crate::Result<T> {
280284
let mut buf = Vec::with_capacity(1024);
281285
self.read_to_end(&mut buf).await?;
@@ -300,6 +304,7 @@ impl Body {
300304
/// use http_types::convert::{Serialize, Deserialize};
301305
///
302306
/// #[derive(Debug, Serialize, Deserialize)]
307+
/// # #[serde(crate = "serde_crate")]
303308
/// struct Cat { name: String }
304309
///
305310
/// let cat = Cat { name: String::from("chashu") };
@@ -309,6 +314,7 @@ impl Body {
309314
/// assert_eq!(&cat.name, "chashu");
310315
/// # Ok(()) }) }
311316
/// ```
317+
#[cfg(feature = "serde")]
312318
pub fn from_form(form: &impl Serialize) -> crate::Result<Self> {
313319
let query = serde_urlencoded::to_string(form)?;
314320
let bytes = query.into_bytes();
@@ -337,6 +343,7 @@ impl Body {
337343
/// use http_types::convert::{Serialize, Deserialize};
338344
///
339345
/// #[derive(Debug, Serialize, Deserialize)]
346+
/// # #[serde(crate = "serde_crate")]
340347
/// struct Cat { name: String }
341348
///
342349
/// let cat = Cat { name: String::from("chashu") };
@@ -346,6 +353,7 @@ impl Body {
346353
/// assert_eq!(&cat.name, "chashu");
347354
/// # Ok(()) }) }
348355
/// ```
356+
#[cfg(feature = "serde")]
349357
pub async fn into_form<T: DeserializeOwned>(self) -> crate::Result<T> {
350358
let s = self.into_string().await?;
351359
Ok(serde_urlencoded::from_str(&s).status(StatusCode::UnprocessableEntity)?)
@@ -486,6 +494,7 @@ impl Debug for Body {
486494
}
487495
}
488496

497+
#[cfg(feature = "serde")]
489498
impl From<serde_json::Value> for Body {
490499
fn from(json_value: serde_json::Value) -> Self {
491500
Self::from_json(&json_value).unwrap()
@@ -577,11 +586,12 @@ fn guess_ext(path: &std::path::Path) -> Option<Mime> {
577586
mod test {
578587
use super::*;
579588
use async_std::io::Cursor;
580-
use serde::Deserialize;
589+
use serde_crate::Deserialize;
581590

582591
#[async_std::test]
583592
async fn json_status() {
584593
#[derive(Debug, Deserialize)]
594+
#[serde(crate = "serde_crate")]
585595
struct Foo {
586596
inner: String,
587597
}
@@ -593,6 +603,7 @@ mod test {
593603
#[async_std::test]
594604
async fn form_status() {
595605
#[derive(Debug, Deserialize)]
606+
#[serde(crate = "serde_crate")]
596607
struct Foo {
597608
inner: String,
598609
}

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ mod hyperium_http;
164164
#[doc(inline)]
165165
pub use crate::extensions::Extensions;
166166

167+
#[cfg(feature = "serde")]
167168
/// Traits for conversions between types.
168169
pub mod convert {
169-
pub use serde::{de::DeserializeOwned, Deserialize, Serialize};
170+
pub use serde_crate::{de::DeserializeOwned, Deserialize, Serialize};
170171
#[doc(inline)]
171172
pub use serde_json::json;
172173
}

src/method.rs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use serde::de::{Error as DeError, Unexpected};
2-
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
31
use std::fmt::{self, Display};
42
use std::str::FromStr;
53

@@ -357,41 +355,50 @@ impl Method {
357355
}
358356
}
359357

360-
struct MethodVisitor;
358+
#[cfg(feature = "serde")]
359+
mod serde {
360+
use super::Method;
361+
use serde_crate::de::{Error as DeError, Unexpected, Visitor};
362+
use serde_crate::{Deserialize, Deserializer, Serialize, Serializer};
363+
use std::fmt;
364+
use std::str::FromStr;
361365

362-
impl<'de> Visitor<'de> for MethodVisitor {
363-
type Value = Method;
366+
struct MethodVisitor;
364367

365-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
366-
write!(formatter, "a HTTP method &str")
367-
}
368+
impl<'de> Visitor<'de> for MethodVisitor {
369+
type Value = Method;
370+
371+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
372+
write!(formatter, "a HTTP method &str")
373+
}
368374

369-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
370-
where
371-
E: DeError,
372-
{
373-
match Method::from_str(v) {
374-
Ok(method) => Ok(method),
375-
Err(_) => Err(DeError::invalid_value(Unexpected::Str(v), &self)),
375+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
376+
where
377+
E: DeError,
378+
{
379+
match Method::from_str(v) {
380+
Ok(method) => Ok(method),
381+
Err(_) => Err(DeError::invalid_value(Unexpected::Str(v), &self)),
382+
}
376383
}
377384
}
378-
}
379385

380-
impl<'de> Deserialize<'de> for Method {
381-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
382-
where
383-
D: Deserializer<'de>,
384-
{
385-
deserializer.deserialize_str(MethodVisitor)
386+
impl<'de> Deserialize<'de> for Method {
387+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
388+
where
389+
D: Deserializer<'de>,
390+
{
391+
deserializer.deserialize_str(MethodVisitor)
392+
}
386393
}
387-
}
388394

389-
impl Serialize for Method {
390-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
391-
where
392-
S: Serializer,
393-
{
394-
serializer.serialize_str(&self.to_string())
395+
impl Serialize for Method {
396+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
397+
where
398+
S: Serializer,
399+
{
400+
serializer.serialize_str(&self.to_string())
401+
}
395402
}
396403
}
397404

src/request.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ use std::ops::Index;
66
use std::pin::Pin;
77
use std::task::{Context, Poll};
88

9+
#[cfg(feature = "serde")]
910
use crate::convert::{DeserializeOwned, Serialize};
1011
use crate::headers::{
1112
self, HeaderName, HeaderValue, HeaderValues, Headers, Names, ToHeaderValues, Values,
1213
CONTENT_TYPE,
1314
};
1415
use crate::mime::Mime;
1516
use crate::trailers::{self, Trailers};
16-
use crate::{Body, Extensions, Method, StatusCode, Url, Version};
17+
use crate::{Body, Extensions, Method, Url, Version};
1718

1819
pin_project_lite::pin_project! {
1920
/// An HTTP request.
@@ -349,6 +350,7 @@ impl Request {
349350
/// use http_types::{Body, Request};
350351
///
351352
/// #[derive(Debug, Serialize, Deserialize)]
353+
/// # #[serde(crate = "serde_crate")]
352354
/// struct Cat {
353355
/// name: String,
354356
/// }
@@ -363,6 +365,7 @@ impl Request {
363365
/// assert_eq!(&cat.name, "chashu");
364366
/// # Ok(()) }) }
365367
/// ```
368+
#[cfg(feature = "serde")]
366369
pub async fn body_json<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
367370
let body = self.take_body();
368371
body.into_json().await
@@ -383,6 +386,7 @@ impl Request {
383386
/// use http_types::{Body, Request};
384387
///
385388
/// #[derive(Debug, Serialize, Deserialize)]
389+
/// # #[serde(crate = "serde_crate")]
386390
/// struct Cat {
387391
/// name: String,
388392
/// }
@@ -397,6 +401,7 @@ impl Request {
397401
/// assert_eq!(&cat.name, "chashu");
398402
/// # Ok(()) }) }
399403
/// ```
404+
#[cfg(feature = "serde")]
400405
pub async fn body_form<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
401406
let body = self.take_body();
402407
body.into_form().await
@@ -616,6 +621,7 @@ impl Request {
616621
/// use std::collections::HashMap;
617622
///
618623
/// #[derive(Deserialize)]
624+
/// # #[serde(crate = "serde_crate")]
619625
/// struct Index {
620626
/// page: u32,
621627
/// selections: HashMap<String, String>,
@@ -627,15 +633,16 @@ impl Request {
627633
/// assert_eq!(selections["width"], "narrow");
628634
/// assert_eq!(selections["height"], "tall");
629635
/// ```
630-
pub fn query<T: serde::de::DeserializeOwned>(&self) -> crate::Result<T> {
636+
#[cfg(feature = "serde")]
637+
pub fn query<T: serde_crate::de::DeserializeOwned>(&self) -> crate::Result<T> {
631638
// Default to an empty query string if no query parameter has been specified.
632639
// This allows successful deserialisation of structs where all fields are optional
633640
// when none of those fields has actually been passed by the caller.
634641
let query = self.url().query().unwrap_or("");
635642
serde_qs::from_str(query).map_err(|e| {
636643
// Return the displayable version of the deserialisation error to the caller
637644
// for easier debugging.
638-
crate::Error::from_str(StatusCode::BadRequest, format!("{}", e))
645+
crate::Error::from_str(crate::StatusCode::BadRequest, format!("{}", e))
639646
})
640647
}
641648

@@ -649,6 +656,7 @@ impl Request {
649656
/// use std::collections::HashMap;
650657
///
651658
/// #[derive(Serialize)]
659+
/// # #[serde(crate = "serde_crate")]
652660
/// struct Index {
653661
/// page: u32,
654662
/// topics: Vec<&'static str>,
@@ -659,9 +667,10 @@ impl Request {
659667
/// req.set_query(&query).unwrap();
660668
/// assert_eq!(req.url().query(), Some("page=2&topics[0]=rust&topics[1]=crabs&topics[2]=crustaceans"));
661669
/// ```
670+
#[cfg(feature = "serde")]
662671
pub fn set_query(&mut self, query: &impl Serialize) -> crate::Result<()> {
663672
let query = serde_qs::to_string(query)
664-
.map_err(|e| crate::Error::from_str(StatusCode::BadRequest, format!("{}", e)))?;
673+
.map_err(|e| crate::Error::from_str(crate::StatusCode::BadRequest, format!("{}", e)))?;
665674
self.url.set_query(Some(&query));
666675
Ok(())
667676
}

src/response.rs

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

10+
#[cfg(feature = "serde")]
1011
use crate::convert::DeserializeOwned;
1112
use crate::headers::{
1213
self, HeaderName, HeaderValue, HeaderValues, Headers, Names, ToHeaderValues, Values,
@@ -313,6 +314,7 @@ impl Response {
313314
/// use http_types::{Body, Method, Response, StatusCode, Url};
314315
///
315316
/// #[derive(Debug, Serialize, Deserialize)]
317+
/// # #[serde(crate = "serde_crate")]
316318
/// struct Cat {
317319
/// name: String,
318320
/// }
@@ -327,6 +329,8 @@ impl Response {
327329
/// assert_eq!(&cat.name, "chashu");
328330
/// # Ok(()) }) }
329331
/// ```
332+
333+
#[cfg(feature = "serde")]
330334
pub async fn body_json<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
331335
let body = self.take_body();
332336
body.into_json().await
@@ -347,6 +351,7 @@ impl Response {
347351
/// use http_types::{Body, Method, Response, StatusCode, Url};
348352
///
349353
/// #[derive(Debug, Serialize, Deserialize)]
354+
/// # #[serde(crate = "serde_crate")]
350355
/// struct Cat {
351356
/// name: String,
352357
/// }
@@ -361,6 +366,7 @@ impl Response {
361366
/// assert_eq!(&cat.name, "chashu");
362367
/// # Ok(()) }) }
363368
/// ```
369+
#[cfg(feature = "serde")]
364370
pub async fn body_form<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
365371
let body = self.take_body();
366372
body.into_form().await

0 commit comments

Comments
 (0)