commit
c5839b94e5
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.4.3"
|
||||
version = "0.5.0"
|
||||
authors = ["Anthony Ramine <n.oxyde@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/nox/serde_urlencoded"
|
||||
@ -18,5 +18,5 @@ test = false
|
||||
[dependencies]
|
||||
dtoa = "0.4.0"
|
||||
itoa = "0.3.0"
|
||||
serde = "0.9.3"
|
||||
serde = "1.0.0"
|
||||
url = "1.0.0"
|
||||
|
145
src/de.rs
145
src/de.rs
@ -1,16 +1,15 @@
|
||||
//! Deserialization support for the `application/x-www-form-urlencoded` format.
|
||||
|
||||
use serde::de;
|
||||
use serde::de::value::{MapDeserializer, ValueDeserializer as SerdeValueDeserializer};
|
||||
use serde::de::{self, IntoDeserializer};
|
||||
|
||||
use serde::de::value::MapDeserializer;
|
||||
use std::borrow::Cow;
|
||||
use std::io::Read;
|
||||
use url::form_urlencoded::Parse as UrlEncodedParse;
|
||||
use url::form_urlencoded::parse;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use serde::de::value::Error;
|
||||
use std::borrow::Cow;
|
||||
use std::io::Read;
|
||||
use std::iter::Map;
|
||||
use std::marker::PhantomData;
|
||||
use url::form_urlencoded::Parse as UrlEncodedParse;
|
||||
use url::form_urlencoded::parse;
|
||||
|
||||
/// Deserializes a `application/x-wwww-url-encoded` value from a `&[u8]`.
|
||||
///
|
||||
@ -27,7 +26,9 @@ use url::form_urlencoded::parse;
|
||||
/// b"bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"),
|
||||
/// Ok(meal));
|
||||
/// ```
|
||||
pub fn from_bytes<T: de::Deserialize>(input: &[u8]) -> Result<T, Error> {
|
||||
pub fn from_bytes<'de, T>(input: &'de [u8]) -> Result<T, Error>
|
||||
where T: de::Deserialize<'de>,
|
||||
{
|
||||
T::deserialize(Deserializer::new(parse(input)))
|
||||
}
|
||||
|
||||
@ -46,14 +47,16 @@ pub fn from_bytes<T: de::Deserialize>(input: &[u8]) -> Result<T, Error> {
|
||||
/// "bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"),
|
||||
/// Ok(meal));
|
||||
/// ```
|
||||
pub fn from_str<T: de::Deserialize>(input: &str) -> Result<T, Error> {
|
||||
pub fn from_str<'de, T>(input: &'de str) -> Result<T, Error>
|
||||
where T: de::Deserialize<'de>,
|
||||
{
|
||||
from_bytes(input.as_bytes())
|
||||
}
|
||||
|
||||
/// Convenience function that reads all bytes from `reader` and deserializes
|
||||
/// them with `from_bytes`.
|
||||
pub fn from_reader<T, R>(mut reader: R) -> Result<T, Error>
|
||||
where T: de::Deserialize,
|
||||
where T: de::DeserializeOwned,
|
||||
R: Read,
|
||||
{
|
||||
let mut buf = vec![];
|
||||
@ -73,53 +76,41 @@ pub fn from_reader<T, R>(mut reader: R) -> Result<T, Error>
|
||||
///
|
||||
/// * Everything else but `deserialize_seq` and `deserialize_seq_fixed_size`
|
||||
/// defers to `deserialize`.
|
||||
pub struct Deserializer<'a> {
|
||||
inner: MapDeserializer<Map<UrlEncodedParse<'a>,
|
||||
fn((Cow<'a, str>, Cow<'a, str>))
|
||||
-> (Cow<'a, str>, Value<'a>)>,
|
||||
Error>,
|
||||
pub struct Deserializer<'de> {
|
||||
inner: MapDeserializer<'de, PartIterator<'de>, Error>,
|
||||
}
|
||||
|
||||
impl<'a> Deserializer<'a> {
|
||||
impl<'de> Deserializer<'de> {
|
||||
/// Returns a new `Deserializer`.
|
||||
pub fn new(parser: UrlEncodedParse<'a>) -> Self {
|
||||
pub fn new(parser: UrlEncodedParse<'de>) -> Self {
|
||||
Deserializer {
|
||||
inner: MapDeserializer::new(parser.map(Value::wrap_pair)),
|
||||
inner: MapDeserializer::new(PartIterator(parser)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> de::Deserializer for Deserializer<'a> {
|
||||
impl<'de> de::Deserializer<'de> for Deserializer<'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor,
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor<'de>,
|
||||
{
|
||||
self.deserialize_map(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor,
|
||||
where V: de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_map(self.inner)
|
||||
}
|
||||
|
||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor,
|
||||
where V: de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_seq(self.inner)
|
||||
}
|
||||
|
||||
fn deserialize_seq_fixed_size<V>(self,
|
||||
_len: usize,
|
||||
visitor: V)
|
||||
-> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit_seq(self.inner)
|
||||
}
|
||||
|
||||
forward_to_deserialize! {
|
||||
forward_to_deserialize_any! {
|
||||
bool
|
||||
u8
|
||||
u16
|
||||
@ -142,68 +133,65 @@ impl<'a> de::Deserializer for Deserializer<'a> {
|
||||
newtype_struct
|
||||
tuple_struct
|
||||
struct
|
||||
struct_field
|
||||
identifier
|
||||
tuple
|
||||
enum
|
||||
ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
struct Value<'a>(Cow<'a, str>);
|
||||
struct PartIterator<'de>(UrlEncodedParse<'de>);
|
||||
|
||||
impl<'a> Value<'a> {
|
||||
fn wrap_pair((k, v): (Cow<'a, str>, Cow<'a, str>)) -> (Cow<'a, str>, Self) {
|
||||
(k, Value(v))
|
||||
impl<'de> Iterator for PartIterator<'de> {
|
||||
type Item = (Part<'de>, Part<'de>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.next().map(|(k, v)| (Part(k), Part(v)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E> SerdeValueDeserializer<E> for Value<'a>
|
||||
where E: de::Error,
|
||||
struct Part<'de>(Cow<'de, str>);
|
||||
|
||||
impl<'de> IntoDeserializer<'de> for Part<'de>
|
||||
{
|
||||
type Deserializer = ValueDeserializer<'a, E>;
|
||||
type Deserializer = Self;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
ValueDeserializer {
|
||||
value: self.0,
|
||||
marker: PhantomData,
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
struct ValueDeserializer<'a, E> {
|
||||
value: Cow<'a, str>,
|
||||
marker: PhantomData<E>,
|
||||
macro_rules! forward_parsed_value {
|
||||
($($ty:ident => $method:ident,)*) => {
|
||||
$(
|
||||
fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor<'de>
|
||||
{
|
||||
match self.0.parse::<$ty>() {
|
||||
Ok(val) => val.into_deserializer().$method(visitor),
|
||||
Err(e) => Err(de::Error::custom(e))
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E> de::Deserializer for ValueDeserializer<'a, E>
|
||||
where E: de::Error,
|
||||
{
|
||||
type Error = E;
|
||||
impl<'de> de::Deserializer<'de> for Part<'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor,
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor<'de>,
|
||||
{
|
||||
self.value.into_deserializer().deserialize(visitor)
|
||||
self.0.into_deserializer().deserialize_any(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor,
|
||||
where V: de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_some(self.value.into_deserializer())
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
|
||||
forward_to_deserialize! {
|
||||
bool
|
||||
u8
|
||||
u16
|
||||
u32
|
||||
u64
|
||||
i8
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
f32
|
||||
f64
|
||||
forward_to_deserialize_any! {
|
||||
char
|
||||
str
|
||||
string
|
||||
@ -214,12 +202,25 @@ impl<'a, E> de::Deserializer for ValueDeserializer<'a, E>
|
||||
newtype_struct
|
||||
tuple_struct
|
||||
struct
|
||||
struct_field
|
||||
identifier
|
||||
tuple
|
||||
enum
|
||||
ignored_any
|
||||
seq
|
||||
seq_fixed_size
|
||||
map
|
||||
}
|
||||
|
||||
forward_parsed_value! {
|
||||
bool => deserialize_bool,
|
||||
u8 => deserialize_u8,
|
||||
u16 => deserialize_u16,
|
||||
u32 => deserialize_u32,
|
||||
u64 => deserialize_u64,
|
||||
i8 => deserialize_i8,
|
||||
i16 => deserialize_i16,
|
||||
i32 => deserialize_i32,
|
||||
i64 => deserialize_i64,
|
||||
f32 => deserialize_f32,
|
||||
f64 => deserialize_f64,
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use url::form_urlencoded::Target as UrlEncodedTarget;
|
||||
/// serde_urlencoded::to_string(meal),
|
||||
/// Ok("bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter".to_owned()));
|
||||
/// ```
|
||||
pub fn to_string<T: ser::Serialize>(input: &T) -> Result<String, Error> {
|
||||
pub fn to_string<T: ser::Serialize>(input: T) -> Result<String, Error> {
|
||||
let mut urlencoder = UrlEncodedSerializer::new("".to_owned());
|
||||
input.serialize(Serializer::new(&mut urlencoder))?;
|
||||
Ok(urlencoder.finish())
|
||||
@ -99,9 +99,9 @@ pub struct SeqSerializer<'output, Target: 'output + UrlEncodedTarget> {
|
||||
|
||||
/// Tuple serializer.
|
||||
///
|
||||
/// Never instantiated, tuples are not supported at top-level.
|
||||
pub struct TupleSerializer<'output, T: 'output + UrlEncodedTarget> {
|
||||
inner: ser::Impossible<&'output mut UrlEncodedSerializer<T>, Error>,
|
||||
/// Mostly used for arrays.
|
||||
pub struct TupleSerializer<'output, Target: 'output + UrlEncodedTarget> {
|
||||
urlencoder: &'output mut UrlEncodedSerializer<Target>,
|
||||
}
|
||||
|
||||
/// Tuple struct serializer.
|
||||
@ -234,7 +234,7 @@ impl<'output, Target> ser::Serializer for Serializer<'output, Target>
|
||||
/// Returns an error.
|
||||
fn serialize_unit_variant(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str)
|
||||
-> Result<Self::Ok, Error> {
|
||||
Err(Error::top_level())
|
||||
@ -253,7 +253,7 @@ impl<'output, Target> ser::Serializer for Serializer<'output, Target>
|
||||
fn serialize_newtype_variant<T: ?Sized + ser::Serialize>
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_value: &T)
|
||||
-> Result<Self::Ok, Error> {
|
||||
@ -280,18 +280,11 @@ impl<'output, Target> ser::Serializer for Serializer<'output, Target>
|
||||
Ok(SeqSerializer { urlencoder: self.urlencoder })
|
||||
}
|
||||
|
||||
/// Serializes a sequence, given length is ignored.
|
||||
fn serialize_seq_fixed_size(self,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeSeq, Error> {
|
||||
Ok(SeqSerializer { urlencoder: self.urlencoder })
|
||||
}
|
||||
|
||||
/// Returns an error.
|
||||
fn serialize_tuple(self,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeTuple, Error> {
|
||||
Err(Error::top_level())
|
||||
Ok(TupleSerializer { urlencoder: self.urlencoder })
|
||||
}
|
||||
|
||||
/// Returns an error.
|
||||
@ -306,7 +299,7 @@ impl<'output, Target> ser::Serializer for Serializer<'output, Target>
|
||||
fn serialize_tuple_variant
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeTupleVariant, Error> {
|
||||
@ -335,7 +328,7 @@ impl<'output, Target> ser::Serializer for Serializer<'output, Target>
|
||||
fn serialize_struct_variant
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeStructVariant, Error> {
|
||||
@ -369,16 +362,17 @@ impl<'output, Target> ser::SerializeTuple for TupleSerializer<'output, Target>
|
||||
fn serialize_element<T: ?Sized + ser::Serialize>(&mut self,
|
||||
value: &T)
|
||||
-> Result<(), Error> {
|
||||
self.inner.serialize_element(value)
|
||||
value.serialize(pair::PairSerializer::new(self.urlencoder))
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Error> {
|
||||
self.inner.end()
|
||||
Ok(self.urlencoder)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'output, Target> ser::SerializeTupleStruct
|
||||
for TupleStructSerializer<'output, Target>
|
||||
for
|
||||
TupleStructSerializer<'output, Target>
|
||||
where Target: 'output + UrlEncodedTarget,
|
||||
{
|
||||
type Ok = &'output mut UrlEncodedSerializer<Target>;
|
||||
@ -396,7 +390,8 @@ impl<'output, Target> ser::SerializeTupleStruct
|
||||
}
|
||||
|
||||
impl<'output, Target> ser::SerializeTupleVariant
|
||||
for TupleVariantSerializer<'output, Target>
|
||||
for
|
||||
TupleVariantSerializer<'output, Target>
|
||||
where Target: 'output + UrlEncodedTarget,
|
||||
{
|
||||
type Ok = &'output mut UrlEncodedSerializer<Target>;
|
||||
@ -480,7 +475,8 @@ impl<'output, Target> ser::SerializeStruct for StructSerializer<'output, Target>
|
||||
}
|
||||
|
||||
impl<'output, Target> ser::SerializeStructVariant
|
||||
for StructVariantSerializer<'output, Target>
|
||||
for
|
||||
StructVariantSerializer<'output, Target>
|
||||
where Target: 'output + UrlEncodedTarget,
|
||||
{
|
||||
type Ok = &'output mut UrlEncodedSerializer<Target>;
|
||||
|
@ -103,7 +103,7 @@ impl<'target, Target> ser::Serializer for PairSerializer<'target, Target>
|
||||
|
||||
fn serialize_unit_variant(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str)
|
||||
-> Result<(), Error> {
|
||||
Err(Error::unsupported_pair())
|
||||
@ -120,7 +120,7 @@ impl<'target, Target> ser::Serializer for PairSerializer<'target, Target>
|
||||
fn serialize_newtype_variant<T: ?Sized + ser::Serialize>
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_value: &T)
|
||||
-> Result<(), Error> {
|
||||
@ -143,12 +143,6 @@ impl<'target, Target> ser::Serializer for PairSerializer<'target, Target>
|
||||
Err(Error::unsupported_pair())
|
||||
}
|
||||
|
||||
fn serialize_seq_fixed_size(self,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeSeq, Error> {
|
||||
Err(Error::unsupported_pair())
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
|
||||
if len == 2 {
|
||||
Ok(self)
|
||||
@ -167,7 +161,7 @@ impl<'target, Target> ser::Serializer for PairSerializer<'target, Target>
|
||||
fn serialize_tuple_variant
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeTupleVariant, Error> {
|
||||
@ -190,7 +184,7 @@ impl<'target, Target> ser::Serializer for PairSerializer<'target, Target>
|
||||
fn serialize_struct_variant
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeStructVariant, Error> {
|
||||
|
@ -113,7 +113,7 @@ impl<S: Sink> ser::Serializer for PartSerializer<S> {
|
||||
|
||||
fn serialize_unit_variant(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
variant: &'static str)
|
||||
-> Result<S::Ok, Error> {
|
||||
self.sink.serialize_static_str(variant.into())
|
||||
@ -130,7 +130,7 @@ impl<S: Sink> ser::Serializer for PartSerializer<S> {
|
||||
fn serialize_newtype_variant<T: ?Sized + ser::Serialize>
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_value: &T)
|
||||
-> Result<S::Ok, Error> {
|
||||
@ -153,13 +153,6 @@ impl<S: Sink> ser::Serializer for PartSerializer<S> {
|
||||
Err(self.sink.unsupported())
|
||||
}
|
||||
|
||||
|
||||
fn serialize_seq_fixed_size(self,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeSeq, Error> {
|
||||
Err(self.sink.unsupported())
|
||||
}
|
||||
|
||||
fn serialize_tuple(self,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeTuple, Error> {
|
||||
@ -176,7 +169,7 @@ impl<S: Sink> ser::Serializer for PartSerializer<S> {
|
||||
fn serialize_tuple_variant
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeTupleVariant, Error> {
|
||||
@ -199,7 +192,7 @@ impl<S: Sink> ser::Serializer for PartSerializer<S> {
|
||||
fn serialize_struct_variant
|
||||
(self,
|
||||
_name: &'static str,
|
||||
_variant_index: usize,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize)
|
||||
-> Result<Self::SerializeStructVariant, Error> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user