Implement deserialization into unit enums

This commit is contained in:
Shaun Mangelsdorf 2018-02-13 11:50:58 +10:00 committed by Anthony Ramine
parent 3ae5332931
commit 4d220818f7
4 changed files with 105 additions and 3 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "serde_urlencoded"
version = "0.5.2"
version = "0.5.3"
authors = ["Anthony Ramine <n.oxyde@gmail.com>"]
license = "MIT/Apache-2.0"
repository = "https://github.com/nox/serde_urlencoded"
@ -20,3 +20,6 @@ dtoa = "0.4.0"
itoa = "0.4.0"
serde = "1.0.0"
url = "1.0.0"
[dev-dependencies]
serde_derive = "1.0"

View File

@ -1,7 +1,7 @@
//! Deserialization support for the `application/x-www-form-urlencoded` format.
use serde::de::{self, IntoDeserializer};
use serde::de::Error as de_Error;
use serde::de::value::MapDeserializer;
use std::borrow::Cow;
use std::io::Read;
@ -197,6 +197,17 @@ impl<'de> de::Deserializer<'de> for Part<'de> {
visitor.visit_some(self)
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where V: de::Visitor<'de>,
{
visitor.visit_enum(ValueEnumAccess(self.0))
}
forward_to_deserialize_any! {
char
str
@ -210,7 +221,6 @@ impl<'de> de::Deserializer<'de> for Part<'de> {
struct
identifier
tuple
enum
ignored_any
seq
map
@ -230,3 +240,56 @@ impl<'de> de::Deserializer<'de> for Part<'de> {
f64 => deserialize_f64,
}
}
struct ValueEnumAccess<'de>(Cow<'de, str>);
impl<'de> de::EnumAccess<'de> for ValueEnumAccess<'de> {
type Error = Error;
type Variant = UnitOnlyVariantAccess;
fn variant_seed<V>(
self,
seed: V,
) -> Result<(V::Value, Self::Variant), Self::Error>
where V: de::DeserializeSeed<'de>,
{
let variant = seed.deserialize(self.0.into_deserializer())?;
Ok((variant, UnitOnlyVariantAccess))
}
}
struct UnitOnlyVariantAccess;
impl<'de> de::VariantAccess<'de> for UnitOnlyVariantAccess {
type Error = Error;
fn unit_variant(self) -> Result<(), Self::Error> {
Ok(())
}
fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
where T: de::DeserializeSeed<'de>,
{
Err(Error::custom("expected unit variant"))
}
fn tuple_variant<V>(
self,
_len: usize,
_visitor: V,
) -> Result<V::Value, Self::Error>
where V: de::Visitor<'de>,
{
Err(Error::custom("expected unit variant"))
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
_visitor: V,
) -> Result<V::Value, Self::Error>
where V: de::Visitor<'de>,
{
Err(Error::custom("expected unit variant"))
}
}

View File

@ -1,4 +1,6 @@
extern crate serde_urlencoded;
#[macro_use]
extern crate serde_derive;
#[test]
fn deserialize_bytes() {
@ -40,3 +42,21 @@ fn deserialize_unit() {
assert_eq!(serde_urlencoded::from_str("&&"), Ok(()));
assert!(serde_urlencoded::from_str::<()>("first=23").is_err());
}
#[derive(Deserialize, Debug, PartialEq, Eq)]
enum X {
A,
B,
C,
}
#[test]
fn deserialize_unit_enum() {
let result = vec![
("one".to_owned(), X::A),
("two".to_owned(), X::B),
("three".to_owned(), X::C)
];
assert_eq!(serde_urlencoded::from_str("one=A&two=B&three=C"), Ok(result));
}

View File

@ -1,4 +1,6 @@
extern crate serde_urlencoded;
#[macro_use]
extern crate serde_derive;
#[test]
fn serialize_option_map_int() {
@ -32,3 +34,17 @@ fn serialize_map_bool() {
assert_eq!(serde_urlencoded::to_string(params),
Ok("one=true&two=false".to_owned()));
}
#[derive(Serialize)]
enum X {
A,
B,
C,
}
#[test]
fn serialize_unit_enum() {
let params = &[("one", X::A), ("two", X::B), ("three", X::C)];
assert_eq!(serde_urlencoded::to_string(params),
Ok("one=A&two=B&three=C".to_owned()));
}