Skip to content

Commit

Permalink
Add support for enums in top level
Browse files Browse the repository at this point in the history
Partially address samscott89#71
  • Loading branch information
sbihel committed Jun 12, 2023
1 parent 8a13b67 commit 78c9f7e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
14 changes: 7 additions & 7 deletions src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@
//! `ParsableStringDeserializer`.

mod parse;

use crate::error::*;

use serde::de;
use serde::de::IntoDeserializer;

use std::borrow::Cow;
use std::collections::btree_map::{BTreeMap, Entry, IntoIter};
use std::iter::Peekable;

/// To override the default serialization parameters, first construct a new
/// Config.
Expand Down Expand Up @@ -190,7 +190,7 @@ pub fn from_str<'de, T: de::Deserialize<'de>>(input: &'de str) -> Result<T> {
///
/// Supported top-level outputs are structs and maps.
pub(crate) struct QsDeserializer<'a> {
iter: IntoIter<Cow<'a, str>, Level<'a>>,
iter: Peekable<IntoIter<Cow<'a, str>, Level<'a>>>,
value: Option<Level<'a>>,
}

Expand All @@ -207,7 +207,7 @@ enum Level<'a> {
impl<'a> QsDeserializer<'a> {
fn with_map(map: BTreeMap<Cow<'a, str>, Level<'a>>) -> Self {
QsDeserializer {
iter: map.into_iter(),
iter: map.into_iter().peekable(),
value: None,
}
}
Expand All @@ -225,11 +225,11 @@ impl<'de> de::Deserializer<'de> for QsDeserializer<'de> {
where
V: de::Visitor<'de>,
{
if self.iter.next().is_none() {
return visitor.visit_unit();
if self.iter.peek().is_none() {
visitor.visit_unit()
} else {
self.deserialize_map(visitor)
}

Err(Error::top_level("primitive"))
}

fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
Expand Down
4 changes: 2 additions & 2 deletions src/de/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ impl<'a> Parser<'a> {
// Parses all top level nodes into the `root` map.
while self.parse(&mut root)? {}
let iter = match root {
Level::Nested(map) => map.into_iter(),
_ => BTreeMap::default().into_iter(),
Level::Nested(map) => map.into_iter().peekable(),
_ => BTreeMap::default().into_iter().peekable(),
};
Ok(QsDeserializer { iter, value: None })
}
Expand Down
45 changes: 45 additions & 0 deletions tests/test_deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,51 @@ fn deserialize_enum_untagged() {
);
}

#[test]
fn deserialize_enum_untagged_top_level() {
#[derive(Deserialize, Debug, PartialEq)]
#[serde(untagged)]
enum E {
B { b: String },
S { s: String },
}

let params = "s=true";
let rec_params: E = qs::from_str(params).unwrap();
assert_eq!(
rec_params,
E::S {
s: "true".to_string()
}
);
let params = "b=test";
let rec_params: E = qs::from_str(params).unwrap();
assert_eq!(
rec_params,
E::B {
b: "test".to_string()
}
);
}

#[test]
fn deserialize_enum_top_level() {
#[derive(Deserialize, Debug, PartialEq)]
enum E {
B { b: String },
S { s: String },
}

let params = "S[s]=test";
let rec_params: E = qs::from_str(params).unwrap();
assert_eq!(
rec_params,
E::S {
s: "test".to_string()
}
);
}

#[test]
fn deserialize_enum_adjacently() {
#[derive(Deserialize, Debug, PartialEq)]
Expand Down

0 comments on commit 78c9f7e

Please sign in to comment.