summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--examples/introduction.rs25
-rw-r--r--src/de/mod.rs26
-rw-r--r--src/de/parse.rs8
-rw-r--r--src/lib.rs13
-rw-r--r--tests/test_deserialize.rs8
6 files changed, 56 insertions, 26 deletions
diff --git a/Cargo.toml b/Cargo.toml
index be764fb..e4f3af7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ keywords = ["serde", "serialization", "querystring"]
license = "MIT/Apache-2.0"
name = "serde_qs"
repository = "https://github.com/samscott89/serde_qs"
-version = "0.1.0"
+version = "0.2.0"
[badges]
diff --git a/examples/introduction.rs b/examples/introduction.rs
index fb70665..4e69f16 100644
--- a/examples/introduction.rs
+++ b/examples/introduction.rs
@@ -60,12 +60,12 @@ fn main() {
// In this form, can also simply use `serde_urlencoded`:
let encoded = urlencoded::to_string(&map).unwrap();
println!("`serde_urlencoded` to_string for map:\n\t{}", encoded);
+ println!("");
// Given this encoded string, you can recover the original map
// as a list of pairs using serde_urlencoded:
let pairs: Vec<(String, String)> = urlencoded::from_str(&encoded).unwrap();
println!("`serde_urlencoded` from_str to pairs:\n\t{:?}", pairs);
-
// However, the best way is to use serde_qs to deserialize the entire thing
// into a struct:
let params: QueryParams = qs::from_str(&encoded).unwrap();
@@ -75,6 +75,8 @@ fn main() {
// Similarly, we can serialize this structure using `serde_qs`:
let encoded = qs::to_string(&params).unwrap();
println!("`serde_qs` to_string for struct:\n\t{:?}", encoded);
+ println!("");
+
// One nice feature is that this gives deterministic encodings:
let encoded2 = qs::to_string(&params).unwrap();
@@ -128,11 +130,11 @@ fn main() {
let params: QueryParams = qs::from_str(encoded).unwrap();
assert_eq!(params, example_params);
- // Enums are supported, but only adjacently tagged enums
- // (see https://serde.rs/enum-representations.html for more information).
+ // Enums are now fully supported! Most formats should work with varying
+ // results.
#[derive(Deserialize, Debug, PartialEq, Serialize)]
- // #[serde(tag = "type", content = "value")]
enum AdjTaggedEnum {
+ A,
B(bool),
S(String),
V { id: u8, v: String },
@@ -147,9 +149,22 @@ fn main() {
e: AdjTaggedEnum::B(false),
};
// encodes as:
- // "e[type]=B&e[value]=false"
+ // "e[B]=false"
let encoded = qs::to_string(&example_params).unwrap();
println!("`serde_qs` to_string for enum:\n\t{:?}", encoded);
let params: EnumQuery = qs::from_str(&encoded).unwrap();
println!("`serde_qs` from_str for enum:\n\t{:?}", params);
+ println!("");
+
+ let example_params = EnumQuery {
+ e: AdjTaggedEnum::A,
+ };
+ // encodes as:
+ // "e=A"
+ let encoded = qs::to_string(&example_params).unwrap();
+ println!("`serde_qs` to_string for enum:\n\t{:?}", encoded);
+ let params: EnumQuery = qs::from_str(&encoded).unwrap();
+ println!("`serde_qs` from_str for enum:\n\t{:?}", params);
+ println!("");
+
}
diff --git a/src/de/mod.rs b/src/de/mod.rs
index 267b4cb..94c66e1 100644
--- a/src/de/mod.rs
+++ b/src/de/mod.rs
@@ -5,11 +5,9 @@ mod parse;
pub use de::parse::Config;
use data_encoding;
-use data_encoding::base64;
use serde::de;
use serde::de::IntoDeserializer;
-use serde::de::value::MapDeserializer;
use url::percent_encoding;
@@ -118,7 +116,7 @@ pub fn from_reader<'de, T, R>(mut reader: R) -> Result<T>
/// A deserializer for the querystring format.
///
/// Supported top-level outputs are structs and maps.
-pub struct Deserializer {
+pub struct QsDeserializer {
iter: IntoIter<String, Level>,
value: Option<Level>,
}
@@ -131,15 +129,15 @@ pub enum Level {
Invalid(&'static str),
}
-impl Deserializer {
+impl QsDeserializer {
fn with_map(map: BTreeMap<String, Level>) -> Self {
- Deserializer {
+ QsDeserializer {
iter: map.into_iter(),
value: None,
}
}
- /// Returns a new `Deserializer`.
+ /// Returns a new `QsDeserializer`.
fn with_config(config: &Config, input: &[u8]) -> Self {
let decoded = percent_encoding::percent_decode(input);
parse::Parser::new(decoded, vec![], None, config.max_depth()).to_deserializer()
@@ -147,7 +145,7 @@ impl Deserializer {
}
}
-impl<'de> de::Deserializer<'de> for Deserializer {
+impl<'de> de::Deserializer<'de> for QsDeserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
@@ -266,7 +264,7 @@ impl<'de> de::Deserializer<'de> for Deserializer {
// use serde::de::IntoDeserializer;
// use serde::de::value::SeqDeserializer;
-impl<'de> de::MapAccess<'de> for Deserializer {
+impl<'de> de::MapAccess<'de> for QsDeserializer {
type Error = Error;
@@ -292,7 +290,7 @@ impl<'de> de::MapAccess<'de> for Deserializer {
}
}
-impl<'de> de::EnumAccess<'de> for Deserializer {
+impl<'de> de::EnumAccess<'de> for QsDeserializer {
type Error = Error;
type Variant = LevelDeserializer;
@@ -406,16 +404,16 @@ macro_rules! deserialize_primitive {
}
impl LevelDeserializer {
- fn to_deserializer(self) -> Result<Deserializer> {
+ fn to_deserializer(self) -> Result<QsDeserializer> {
match self.0 {
Level::Nested(map) => {
- Ok(Deserializer::with_map(map))
+ Ok(QsDeserializer::with_map(map))
},
Level::Invalid(e) => {
Err(de::Error::custom(e))
}
l => {
- Err(de::Error::custom(format!("could not convert {:?} to Deserializer", l)))
+ Err(de::Error::custom(format!("could not convert {:?} to QsDeserializer", l)))
},
}
}
@@ -429,7 +427,7 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer {
{
match self.0 {
Level::Nested(_) => {
- // Deserializer::with_map(map).deserialize_map(visitor)
+ // QsDeserializer::with_map(map).deserialize_map(visitor)
self.deserialize_map(visitor)
},
Level::Sequence(_) => {
@@ -487,7 +485,7 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer {
{
match self.0 {
Level::Nested(map) => {
- Deserializer::with_map(map).deserialize_enum(name, variants, visitor)
+ QsDeserializer::with_map(map).deserialize_enum(name, variants, visitor)
},
Level::Flat(_) => {
visitor.visit_enum(self)
diff --git a/src/de/parse.rs b/src/de/parse.rs
index 7a647db..1f91f07 100644
--- a/src/de/parse.rs
+++ b/src/de/parse.rs
@@ -10,6 +10,8 @@ use super::*;
/// to prevent denial of service attacks by providing incredibly deeply nested
/// inputs.
///
+/// The default value for `max_depth` is 5.
+///
/// ```
/// use serde_qs::de::Config;
/// use std::collections::HashMap;
@@ -53,7 +55,7 @@ impl Config {
pub fn deserialize_bytes<'de, T: de::Deserialize<'de>>(&self,
input: &[u8])
-> Result<T> {
- T::deserialize(Deserializer::with_config(self, input))
+ T::deserialize(QsDeserializer::with_config(self, input))
}
pub fn deserialize_str<'de, T: de::Deserialize<'de>>(&self,
@@ -129,7 +131,7 @@ impl<I: Iterator<Item = u8>> Parser<I> {
}
}
- pub fn to_deserializer(mut self) -> Deserializer {
+ pub fn to_deserializer(mut self) -> QsDeserializer {
let map = BTreeMap::default();
let mut root = Level::Nested(map);
while let Ok(x) = self.parse(&mut root) {
@@ -141,7 +143,7 @@ impl<I: Iterator<Item = u8>> Parser<I> {
Level::Nested(map) => map.into_iter(),
_ => panic!(""),
};
- Deserializer {
+ QsDeserializer {
iter: iter,
value: None,
}
diff --git a/src/lib.rs b/src/lib.rs
index 10b30f3..0e2e9d7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,8 +12,15 @@
//! recommended that the `serde_urlencoded` crate is used instead, which
//! will almost certainly perform better for deserializing simple inputs.
//!
-//! The serialization implementation of this library is adapted from
-//! `serde_urlencoded`.
+//! ## Supported Types
+//!
+//! At the **top level**, `serde_qs` only supports `struct`, `map`, and `enum`.
+//! These are the only top-level structs which can be de/serialized since
+//! Querystrings rely on having a (key, value) pair for each field, which
+//! necessitates this kind of structure.
+//!
+//! However, after the top level you should find all supported types can be
+//! de/serialized.
//!
//! ## Usage
//!
@@ -72,7 +79,7 @@ pub mod de;
pub mod ser;
#[doc(inline)]
-pub use de::{Deserializer, from_bytes, from_reader, from_str};
+pub use de::{QsDeserializer, from_bytes, from_reader, from_str};
#[doc(inline)]
pub use de::Config;
#[doc(inline)]
diff --git a/tests/test_deserialize.rs b/tests/test_deserialize.rs
index 5d6d2c6..3e0c843 100644
--- a/tests/test_deserialize.rs
+++ b/tests/test_deserialize.rs
@@ -367,4 +367,12 @@ fn deserialize_enum() {
let params = "e[S]=other&u=1";
let rec_params: Query = qs::from_str(params).unwrap();
assert_eq!(rec_params, Query { e: E::S("other".to_string()), v: None, u: NewU8(1) });
+
+ let params = "B=";
+ let rec_params: E = qs::from_str(params).unwrap();
+ assert_eq!(rec_params, E::B);
+
+ let params = "S=Hello+World";
+ let rec_params: E = qs::from_str(params).unwrap();
+ assert_eq!(rec_params, E::S("Hello World".to_string()));
}