Skip to content

Commit c87c466

Browse files
committed
use serde_qs for querystrings
1 parent 0836aa5 commit c87c466

File tree

3 files changed

+31
-24
lines changed

3 files changed

+31
-24
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ serde_json = "1.0.51"
4040
serde = { version = "1.0.106", features = ["derive"] }
4141
serde_urlencoded = "0.6.1"
4242
rand = "0.7.3"
43+
serde_qs = "0.6.0"
4344

4445
[dev-dependencies]
4546
http = "0.2.0"

src/request.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -615,31 +615,32 @@ impl Request {
615615
///
616616
/// # Examples
617617
///
618-
/// ```no_run
619-
/// # #[async_std::main]
620-
/// # async fn main() -> http_types::Result<()> {
621-
/// use http_types::convert::{Deserialize, Serialize};
618+
/// ```
619+
/// use http_types::convert::Deserialize;
622620
/// use http_types::{Method, Request, Url};
621+
/// use std::collections::HashMap;
623622
///
624-
/// #[derive(Serialize, Deserialize)]
623+
/// #[derive(Deserialize)]
625624
/// struct Index {
626625
/// page: u32,
626+
/// selections: HashMap<String, String>,
627627
/// }
628628
///
629629
/// let req = Request::new(
630630
/// Method::Get,
631-
/// Url::parse("https://httpbin.org/get?page=2").unwrap(),
631+
/// Url::parse("https://httpbin.org/get?page=2&selections[width]=narrow&selections[height]=tall").unwrap(),
632632
/// );
633-
/// let Index { page } = req.query()?;
633+
/// let Index { page, selections } = req.query().unwrap();
634634
/// assert_eq!(page, 2);
635-
/// # Ok(()) }
635+
/// assert_eq!(selections["width"], "narrow");
636+
/// assert_eq!(selections["height"], "tall");
636637
/// ```
637638
pub fn query<T: serde::de::DeserializeOwned>(&self) -> crate::Result<T> {
638639
// Default to an empty query string if no query parameter has been specified.
639640
// This allows successful deserialisation of structs where all fields are optional
640641
// when none of those fields has actually been passed by the caller.
641642
let query = self.url().query().unwrap_or("");
642-
serde_urlencoded::from_str(query).map_err(|e| {
643+
serde_qs::from_str(query).map_err(|e| {
643644
// Return the displayable version of the deserialisation error to the caller
644645
// for easier debugging.
645646
crate::Error::from_str(StatusCode::BadRequest, format!("{}", e))
@@ -650,29 +651,28 @@ impl Request {
650651
///
651652
/// # Examples
652653
///
653-
/// ```no_run
654-
/// # #[async_std::main]
655-
/// # async fn main() -> http_types::Result<()> {
656-
/// use http_types::convert::{Deserialize, Serialize};
654+
/// ```
655+
/// use http_types::convert::Serialize;
657656
/// use http_types::{Method, Request, Url};
657+
/// use std::collections::HashMap;
658658
///
659-
/// #[derive(Serialize, Deserialize)]
659+
/// #[derive(Serialize)]
660660
/// struct Index {
661661
/// page: u32,
662+
/// topics: Vec<&'static str>,
662663
/// }
663664
///
664-
/// let query = Index { page: 2 };
665+
/// let query = Index { page: 2, topics: vec!["rust", "crabs", "crustaceans"] };
665666
/// let mut req = Request::new(
666667
/// Method::Get,
667-
/// Url::parse("https://httpbin.org/get?page=2").unwrap(),
668+
/// Url::parse("https://httpbin.org/get").unwrap(),
668669
/// );
669-
/// req.set_query(&query)?;
670-
/// assert_eq!(req.url().query(), Some("page=2"));
671-
/// assert_eq!(req.url().as_str(), "https://httpbin.org/get?page=2");
672-
/// # Ok(()) }
670+
/// req.set_query(&query).unwrap();
671+
/// assert_eq!(req.url().query(), Some("page=2&topics[0]=rust&topics[1]=crabs&topics[2]=crustaceans"));
673672
/// ```
674-
pub fn set_query(&mut self, query: &(impl Serialize + ?Sized)) -> crate::Result<()> {
675-
let query = serde_urlencoded::to_string(query)?;
673+
pub fn set_query(&mut self, query: &impl Serialize) -> crate::Result<()> {
674+
let query = serde_qs::to_string(query)
675+
.map_err(|e| crate::Error::from_str(StatusCode::BadRequest, format!("{}", e)))?;
676676
self.url.set_query(Some(&query));
677677
Ok(())
678678
}

tests/querystring.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ fn unsuccessfully_deserialize_query() {
3030

3131
let params = req.query::<Params>();
3232
assert!(params.is_err());
33-
assert_eq!(params.err().unwrap().to_string(), "missing field `msg`");
33+
assert_eq!(
34+
params.err().unwrap().to_string(),
35+
"failed with reason: missing field `msg`"
36+
);
3437
}
3538

3639
#[test]
@@ -42,7 +45,10 @@ fn malformatted_query() {
4245

4346
let params = req.query::<Params>();
4447
assert!(params.is_err());
45-
assert_eq!(params.err().unwrap().to_string(), "missing field `msg`");
48+
assert_eq!(
49+
params.err().unwrap().to_string(),
50+
"failed with reason: missing field `msg`"
51+
);
4652
}
4753

4854
#[test]

0 commit comments

Comments
 (0)