Merge branch master into origin/usize
Conflicts: serde_codegen/src/de.rs testing/tests/test_de.rs
This commit is contained in:
commit
ea702755a2
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "0.9.0-rc1"
|
||||
version = "0.9.0-rc2"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
@ -9,6 +9,7 @@ repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://docs.serde.rs/serde/"
|
||||
readme = "../README.md"
|
||||
keywords = ["serde", "serialization"]
|
||||
categories = ["encoding"]
|
||||
include = ["Cargo.toml", "src/**/*.rs"]
|
||||
|
||||
[features]
|
||||
|
@ -181,6 +181,10 @@ mod bytebuf {
|
||||
impl de::Visitor for ByteBufVisitor {
|
||||
type Value = ByteBuf;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("byte array")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<ByteBuf, E>
|
||||
where E: de::Error,
|
||||
|
@ -32,6 +32,7 @@ use collections::enum_set::{CLike, EnumSet};
|
||||
#[cfg(all(feature = "unstable", feature = "collections"))]
|
||||
use collections::borrow::ToOwned;
|
||||
|
||||
use core::fmt;
|
||||
use core::hash::{Hash, BuildHasher};
|
||||
use core::marker::PhantomData;
|
||||
#[cfg(feature = "std")]
|
||||
@ -60,6 +61,7 @@ use std::time::Duration;
|
||||
use core::nonzero::{NonZero, Zeroable};
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
#[allow(deprecated)] // required for impl Deserialize for NonZero<T>
|
||||
use core::num::Zero;
|
||||
|
||||
use de::{
|
||||
@ -69,7 +71,7 @@ use de::{
|
||||
Error,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
Type,
|
||||
Unexpected,
|
||||
VariantVisitor,
|
||||
Visitor,
|
||||
};
|
||||
@ -83,6 +85,10 @@ pub struct UnitVisitor;
|
||||
impl Visitor for UnitVisitor {
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("unit")
|
||||
}
|
||||
|
||||
fn visit_unit<E>(self) -> Result<(), E>
|
||||
where E: Error,
|
||||
{
|
||||
@ -112,6 +118,10 @@ pub struct BoolVisitor;
|
||||
impl Visitor for BoolVisitor {
|
||||
type Value = bool;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a boolean")
|
||||
}
|
||||
|
||||
fn visit_bool<E>(self, v: bool) -> Result<bool, E>
|
||||
where E: Error,
|
||||
{
|
||||
@ -124,7 +134,7 @@ impl Visitor for BoolVisitor {
|
||||
match s.trim_matches(::utils::Pattern_White_Space) {
|
||||
"true" => Ok(true),
|
||||
"false" => Ok(false),
|
||||
_ => Err(Error::invalid_type(Type::Bool)),
|
||||
_ => Err(Error::invalid_type(Unexpected::Str(s), &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,70 +150,59 @@ impl Deserialize for bool {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! impl_deserialize_num_method {
|
||||
($src_ty:ty, $method:ident, $from_method:ident, $ty:expr) => {
|
||||
($ty:ident, $src_ty:ident, $method:ident, $from_method:ident, $group:ident, $group_ty:ident) => {
|
||||
#[inline]
|
||||
fn $method<E>(self, v: $src_ty) -> Result<T, E>
|
||||
fn $method<E>(self, v: $src_ty) -> Result<$ty, E>
|
||||
where E: Error,
|
||||
{
|
||||
match FromPrimitive::$from_method(v) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(Error::invalid_type($ty)),
|
||||
None => Err(Error::invalid_value(Unexpected::$group(v as $group_ty), &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A visitor that produces a primitive type.
|
||||
struct PrimitiveVisitor<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> PrimitiveVisitor<T> {
|
||||
/// Construct a new `PrimitiveVisitor`.
|
||||
#[inline]
|
||||
fn new() -> Self {
|
||||
PrimitiveVisitor {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for PrimitiveVisitor<T>
|
||||
where T: Deserialize + FromPrimitive + str::FromStr
|
||||
{
|
||||
type Value = T;
|
||||
|
||||
impl_deserialize_num_method!(isize, visit_isize, from_isize, Type::Isize);
|
||||
impl_deserialize_num_method!(i8, visit_i8, from_i8, Type::I8);
|
||||
impl_deserialize_num_method!(i16, visit_i16, from_i16, Type::I16);
|
||||
impl_deserialize_num_method!(i32, visit_i32, from_i32, Type::I32);
|
||||
impl_deserialize_num_method!(i64, visit_i64, from_i64, Type::I64);
|
||||
impl_deserialize_num_method!(usize, visit_usize, from_usize, Type::Usize);
|
||||
impl_deserialize_num_method!(u8, visit_u8, from_u8, Type::U8);
|
||||
impl_deserialize_num_method!(u16, visit_u16, from_u16, Type::U16);
|
||||
impl_deserialize_num_method!(u32, visit_u32, from_u32, Type::U32);
|
||||
impl_deserialize_num_method!(u64, visit_u64, from_u64, Type::U64);
|
||||
impl_deserialize_num_method!(f32, visit_f32, from_f32, Type::F32);
|
||||
impl_deserialize_num_method!(f64, visit_f64, from_f64, Type::F64);
|
||||
|
||||
#[inline]
|
||||
fn visit_str<E>(self, s: &str) -> Result<T, E>
|
||||
where E: Error,
|
||||
{
|
||||
str::FromStr::from_str(s.trim_matches(::utils::Pattern_White_Space)).or_else(|_| {
|
||||
Err(Error::invalid_type(Type::Str))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_deserialize_num {
|
||||
($ty:ty, $method:ident) => {
|
||||
($ty:ident, $method:ident) => {
|
||||
impl Deserialize for $ty {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<$ty, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.$method(PrimitiveVisitor::new())
|
||||
struct PrimitiveVisitor;
|
||||
|
||||
impl Visitor for PrimitiveVisitor {
|
||||
type Value = $ty;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(stringify!($ty))
|
||||
}
|
||||
|
||||
impl_deserialize_num_method!($ty, isize, visit_isize, from_isize, Signed, i64);
|
||||
impl_deserialize_num_method!($ty, i8, visit_i8, from_i8, Signed, i64);
|
||||
impl_deserialize_num_method!($ty, i16, visit_i16, from_i16, Signed, i64);
|
||||
impl_deserialize_num_method!($ty, i32, visit_i32, from_i32, Signed, i64);
|
||||
impl_deserialize_num_method!($ty, i64, visit_i64, from_i64, Signed, i64);
|
||||
impl_deserialize_num_method!($ty, usize, visit_usize, from_usize, Unsigned, u64);
|
||||
impl_deserialize_num_method!($ty, u8, visit_u8, from_u8, Unsigned, u64);
|
||||
impl_deserialize_num_method!($ty, u16, visit_u16, from_u16, Unsigned, u64);
|
||||
impl_deserialize_num_method!($ty, u32, visit_u32, from_u32, Unsigned, u64);
|
||||
impl_deserialize_num_method!($ty, u64, visit_u64, from_u64, Unsigned, u64);
|
||||
impl_deserialize_num_method!($ty, f32, visit_f32, from_f32, Float, f64);
|
||||
impl_deserialize_num_method!($ty, f64, visit_f64, from_f64, Float, f64);
|
||||
|
||||
#[inline]
|
||||
fn visit_str<E>(self, s: &str) -> Result<$ty, E>
|
||||
where E: Error,
|
||||
{
|
||||
str::FromStr::from_str(s.trim_matches(::utils::Pattern_White_Space)).or_else(|_| {
|
||||
Err(Error::invalid_type(Unexpected::Str(s), &self))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.$method(PrimitiveVisitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -229,6 +228,10 @@ struct CharVisitor;
|
||||
impl Visitor for CharVisitor {
|
||||
type Value = char;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a character")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_char<E>(self, v: char) -> Result<char, E>
|
||||
where E: Error,
|
||||
@ -241,14 +244,9 @@ impl Visitor for CharVisitor {
|
||||
where E: Error,
|
||||
{
|
||||
let mut iter = v.chars();
|
||||
if let Some(v) = iter.next() {
|
||||
if iter.next().is_some() {
|
||||
Err(Error::invalid_type(Type::Char))
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
} else {
|
||||
Err(Error::end_of_stream())
|
||||
match (iter.next(), iter.next()) {
|
||||
(Some(c), None) => Ok(c),
|
||||
_ => Err(Error::invalid_value(Unexpected::Str(v), &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,6 +269,10 @@ struct StringVisitor;
|
||||
impl Visitor for StringVisitor {
|
||||
type Value = String;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<String, E>
|
||||
where E: Error,
|
||||
{
|
||||
@ -294,7 +296,7 @@ impl Visitor for StringVisitor {
|
||||
{
|
||||
match str::from_utf8(v) {
|
||||
Ok(s) => Ok(s.to_owned()),
|
||||
Err(_) => Err(Error::invalid_type(Type::String)),
|
||||
Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +305,7 @@ impl Visitor for StringVisitor {
|
||||
{
|
||||
match String::from_utf8(v) {
|
||||
Ok(s) => Ok(s),
|
||||
Err(_) => Err(Error::invalid_type(Type::String)),
|
||||
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,6 +330,10 @@ impl<
|
||||
> Visitor for OptionVisitor<T> {
|
||||
type Value = Option<T>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("option")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<Option<T>, E>
|
||||
where E: Error,
|
||||
@ -368,6 +374,10 @@ pub struct PhantomDataVisitor<T> {
|
||||
impl<T> Visitor for PhantomDataVisitor<T> {
|
||||
type Value = PhantomData<T>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("unit")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<PhantomData<T>, E>
|
||||
where E: Error,
|
||||
@ -417,6 +427,10 @@ macro_rules! seq_impl {
|
||||
{
|
||||
type Value = $ty;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a sequence")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<$ty, E>
|
||||
where E: Error,
|
||||
@ -531,6 +545,10 @@ impl<A> ArrayVisitor<A> {
|
||||
impl<T> Visitor for ArrayVisitor<[T; 0]> where T: Deserialize {
|
||||
type Value = [T; 0];
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("an empty array")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<[T; 0], E>
|
||||
where E: Error,
|
||||
@ -562,6 +580,10 @@ macro_rules! array_impls {
|
||||
impl<T> Visitor for ArrayVisitor<[T; $len]> where T: Deserialize {
|
||||
type Value = [T; $len];
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(concat!("an array of length ", $len))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(self, mut visitor: V) -> Result<[T; $len], V::Error>
|
||||
where V: SeqVisitor,
|
||||
@ -569,7 +591,7 @@ macro_rules! array_impls {
|
||||
$(
|
||||
let $name = match try!(visitor.visit()) {
|
||||
Some(val) => val,
|
||||
None => return Err(Error::end_of_stream()),
|
||||
None => return Err(Error::invalid_length(0, &self)),
|
||||
};
|
||||
)+
|
||||
|
||||
@ -645,6 +667,10 @@ macro_rules! tuple_impls {
|
||||
impl<$($name: Deserialize),+> Visitor for $visitor<$($name,)+> {
|
||||
type Value = ($($name,)+);
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(concat!("a tuple of size ", $len))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn visit_seq<V>(self, mut visitor: V) -> Result<($($name,)+), V::Error>
|
||||
@ -653,7 +679,7 @@ macro_rules! tuple_impls {
|
||||
$(
|
||||
let $name = match try!(visitor.visit()) {
|
||||
Some(value) => value,
|
||||
None => return Err(Error::end_of_stream()),
|
||||
None => return Err(Error::invalid_length(0, &self)),
|
||||
};
|
||||
)+
|
||||
|
||||
@ -723,6 +749,10 @@ macro_rules! map_impl {
|
||||
{
|
||||
type Value = $ty;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a map")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<$ty, E>
|
||||
where E: Error,
|
||||
@ -785,7 +815,7 @@ impl Deserialize for net::IpAddr {
|
||||
let s = try!(String::deserialize(deserializer));
|
||||
match s.parse() {
|
||||
Ok(s) => Ok(s),
|
||||
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
|
||||
Err(err) => Err(D::Error::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -798,7 +828,7 @@ impl Deserialize for net::Ipv4Addr {
|
||||
let s = try!(String::deserialize(deserializer));
|
||||
match s.parse() {
|
||||
Ok(s) => Ok(s),
|
||||
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
|
||||
Err(err) => Err(D::Error::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -811,7 +841,7 @@ impl Deserialize for net::Ipv6Addr {
|
||||
let s = try!(String::deserialize(deserializer));
|
||||
match s.parse() {
|
||||
Ok(s) => Ok(s),
|
||||
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
|
||||
Err(err) => Err(D::Error::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -826,7 +856,7 @@ impl Deserialize for net::SocketAddr {
|
||||
let s = try!(String::deserialize(deserializer));
|
||||
match s.parse() {
|
||||
Ok(s) => Ok(s),
|
||||
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
|
||||
Err(err) => Err(D::Error::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -839,7 +869,7 @@ impl Deserialize for net::SocketAddrV4 {
|
||||
let s = try!(String::deserialize(deserializer));
|
||||
match s.parse() {
|
||||
Ok(s) => Ok(s),
|
||||
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
|
||||
Err(err) => Err(D::Error::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -852,7 +882,7 @@ impl Deserialize for net::SocketAddrV6 {
|
||||
let s = try!(String::deserialize(deserializer));
|
||||
match s.parse() {
|
||||
Ok(s) => Ok(s),
|
||||
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
|
||||
Err(err) => Err(D::Error::custom(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -866,6 +896,10 @@ struct PathBufVisitor;
|
||||
impl Visitor for PathBufVisitor {
|
||||
type Value = path::PathBuf;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("path string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<path::PathBuf, E>
|
||||
where E: Error,
|
||||
{
|
||||
@ -875,7 +909,7 @@ impl Visitor for PathBufVisitor {
|
||||
fn visit_string<E>(self, v: String) -> Result<path::PathBuf, E>
|
||||
where E: Error,
|
||||
{
|
||||
self.visit_str(&v)
|
||||
Ok(From::from(v))
|
||||
}
|
||||
}
|
||||
|
||||
@ -977,13 +1011,17 @@ impl Deserialize for Duration {
|
||||
impl Visitor for FieldVisitor {
|
||||
type Value = Field;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("`secs` or `nanos`")
|
||||
}
|
||||
|
||||
fn visit_usize<E>(self, value: usize) -> Result<Field, E>
|
||||
where E: Error,
|
||||
{
|
||||
match value {
|
||||
0usize => Ok(Field::Secs),
|
||||
1usize => Ok(Field::Nanos),
|
||||
_ => Err(Error::invalid_value("expected a field")),
|
||||
_ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -993,7 +1031,7 @@ impl Deserialize for Duration {
|
||||
match value {
|
||||
"secs" => Ok(Field::Secs),
|
||||
"nanos" => Ok(Field::Nanos),
|
||||
_ => Err(Error::unknown_field(value)),
|
||||
_ => Err(Error::unknown_field(value, FIELDS)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1005,7 +1043,7 @@ impl Deserialize for Duration {
|
||||
b"nanos" => Ok(Field::Nanos),
|
||||
_ => {
|
||||
let value = String::from_utf8_lossy(value);
|
||||
Err(Error::unknown_field(&value))
|
||||
Err(Error::unknown_field(&value, FIELDS))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1020,19 +1058,23 @@ impl Deserialize for Duration {
|
||||
impl Visitor for DurationVisitor {
|
||||
type Value = Duration;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("struct Duration")
|
||||
}
|
||||
|
||||
fn visit_seq<V>(self, mut visitor: V) -> Result<Duration, V::Error>
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
let secs: u64 = match try!(visitor.visit()) {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
return Err(Error::invalid_length(0));
|
||||
return Err(Error::invalid_length(0, &self));
|
||||
}
|
||||
};
|
||||
let nanos: u32 = match try!(visitor.visit()) {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
return Err(Error::invalid_length(1));
|
||||
return Err(Error::invalid_length(1, &self));
|
||||
}
|
||||
};
|
||||
Ok(Duration::new(secs, nanos))
|
||||
@ -1061,11 +1103,11 @@ impl Deserialize for Duration {
|
||||
}
|
||||
let secs = match secs {
|
||||
Some(secs) => secs,
|
||||
None => try!(visitor.missing_field("secs")),
|
||||
None => return Err(<V::Error as Error>::missing_field("secs")),
|
||||
};
|
||||
let nanos = match nanos {
|
||||
Some(nanos) => nanos,
|
||||
None => try!(visitor.missing_field("nanos")),
|
||||
None => return Err(<V::Error as Error>::missing_field("nanos")),
|
||||
};
|
||||
Ok(Duration::new(secs, nanos))
|
||||
}
|
||||
@ -1079,11 +1121,12 @@ impl Deserialize for Duration {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
#[allow(deprecated)] // num::Zero is deprecated but there is no replacement
|
||||
impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable + Zero {
|
||||
fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error> where D: Deserializer {
|
||||
let value = try!(Deserialize::deserialize(deserializer));
|
||||
if value == Zero::zero() {
|
||||
return Err(Error::invalid_value("expected a non-zero value"))
|
||||
return Err(Error::custom("expected a non-zero value"))
|
||||
}
|
||||
unsafe {
|
||||
Ok(NonZero::new(value))
|
||||
@ -1112,23 +1155,15 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
impl Visitor for FieldVisitor {
|
||||
type Value = Field;
|
||||
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn visit_usize<E>(self, value: usize) -> Result<Field, E> where E: Error {
|
||||
#[cfg(feature = "collections")]
|
||||
use collections::string::ToString;
|
||||
match value {
|
||||
0 => Ok(Field::Ok),
|
||||
1 => Ok(Field::Err),
|
||||
_ => Err(Error::unknown_field(&value.to_string())),
|
||||
}
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("`Ok` or `Err`")
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
fn visit_usize<E>(self, value: usize) -> Result<Field, E> where E: Error {
|
||||
match value {
|
||||
0 => Ok(Field::Ok),
|
||||
1 => Ok(Field::Err),
|
||||
_ => Err(Error::unknown_field("some number")),
|
||||
_ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1136,7 +1171,7 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
match value {
|
||||
"Ok" => Ok(Field::Ok),
|
||||
"Err" => Ok(Field::Err),
|
||||
_ => Err(Error::unknown_field(value)),
|
||||
_ => Err(Error::unknown_variant(value, VARIANTS)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1146,8 +1181,8 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
b"Err" => Ok(Field::Err),
|
||||
_ => {
|
||||
match str::from_utf8(value) {
|
||||
Ok(value) => Err(Error::unknown_field(value)),
|
||||
Err(_) => Err(Error::invalid_type(Type::String)),
|
||||
Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
|
||||
Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1166,6 +1201,10 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
{
|
||||
type Value = Result<T, E>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("enum Result")
|
||||
}
|
||||
|
||||
fn visit_enum<V>(self, visitor: V) -> Result<Result<T, E>, V::Error>
|
||||
where V: EnumVisitor
|
||||
{
|
||||
@ -1198,6 +1237,10 @@ impl Deserialize for IgnoredAny {
|
||||
impl Visitor for IgnoredAnyVisitor {
|
||||
type Value = IgnoredAny;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("anything at all")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_bool<E>(self, _: bool) -> Result<IgnoredAny, E> {
|
||||
Ok(IgnoredAny)
|
||||
|
File diff suppressed because it is too large
Load Diff
40
serde/src/de/private.rs
Normal file
40
serde/src/de/private.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use de::{Deserialize, Deserializer, Error, Visitor};
|
||||
|
||||
/// If the missing field is of type `Option<T>` then treat is as `None`,
|
||||
/// otherwise it is an error.
|
||||
pub fn missing_field<V, E>(field: &'static str) -> Result<V, E>
|
||||
where V: Deserialize,
|
||||
E: Error
|
||||
{
|
||||
struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);
|
||||
|
||||
impl<E> Deserializer for MissingFieldDeserializer<E>
|
||||
where E: Error
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn deserialize<V>(self, _visitor: V) -> Result<V::Value, E>
|
||||
where V: Visitor
|
||||
{
|
||||
Err(Error::missing_field(self.0))
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
|
||||
where V: Visitor
|
||||
{
|
||||
visitor.visit_none()
|
||||
}
|
||||
|
||||
forward_to_deserialize! {
|
||||
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
|
||||
string unit seq seq_fixed_size bytes byte_buf map unit_struct
|
||||
newtype_struct tuple_struct struct struct_field tuple enum
|
||||
ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
let deserializer = MissingFieldDeserializer(field, PhantomData);
|
||||
Deserialize::deserialize(deserializer)
|
||||
}
|
@ -28,6 +28,10 @@ use collections::{
|
||||
};
|
||||
#[cfg(all(feature = "collections", not(feature = "std")))]
|
||||
use collections::borrow::Cow;
|
||||
#[cfg(all(feature = "collections", not(feature = "std")))]
|
||||
use collections::boxed::Box;
|
||||
#[cfg(all(feature = "collections", not(feature = "std")))]
|
||||
use collections::string::ToString;
|
||||
|
||||
#[cfg(all(feature = "unstable", feature = "collections"))]
|
||||
use collections::borrow::ToOwned;
|
||||
@ -38,112 +42,57 @@ use std::error;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use error;
|
||||
|
||||
use core::fmt;
|
||||
use core::fmt::{self, Display};
|
||||
use core::iter::{self, Iterator};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use de::{self, SeqVisitor};
|
||||
use de::{self, Expected, SeqVisitor};
|
||||
use bytes;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// This represents all the possible errors that can occur using the `ValueDeserializer`.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
/// The value had some custom error.
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
Custom(String),
|
||||
/// The value had some custom error.
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
Custom(&'static str),
|
||||
pub struct Error(ErrorImpl);
|
||||
|
||||
/// The value had an incorrect type.
|
||||
InvalidType(de::Type),
|
||||
|
||||
/// The value had an invalid length.
|
||||
InvalidLength(usize),
|
||||
|
||||
/// The value is invalid and cannot be deserialized.
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
InvalidValue(String),
|
||||
/// The value is invalid and cannot be deserialized.
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
InvalidValue(&'static str),
|
||||
|
||||
/// EOF while deserializing a value.
|
||||
EndOfStream,
|
||||
|
||||
/// Unknown variant in enum.
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
UnknownVariant(String),
|
||||
/// Unknown variant in enum.
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
UnknownVariant(&'static str),
|
||||
|
||||
/// Unknown field in struct.
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
UnknownField(String),
|
||||
/// Unknown field in struct.
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
UnknownField(&'static str),
|
||||
|
||||
/// Struct is missing a field.
|
||||
MissingField(&'static str),
|
||||
}
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
type ErrorImpl = Box<str>;
|
||||
#[cfg(not(any(feature = "std", feature = "collections")))]
|
||||
type ErrorImpl = ();
|
||||
|
||||
impl de::Error for Error {
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn custom<T: Into<String>>(msg: T) -> Self { Error::Custom(msg.into()) }
|
||||
fn custom<T: Display>(msg: T) -> Self {
|
||||
Error(msg.to_string().into_boxed_str())
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
fn custom<T: Into<&'static str>>(msg: T) -> Self { Error::Custom(msg.into()) }
|
||||
|
||||
fn end_of_stream() -> Self { Error::EndOfStream }
|
||||
fn invalid_type(ty: de::Type) -> Self { Error::InvalidType(ty) }
|
||||
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn invalid_value(msg: &str) -> Self { Error::InvalidValue(msg.to_owned()) }
|
||||
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
fn invalid_value(msg: &str) -> Self { Error::InvalidValue("invalid value") }
|
||||
|
||||
fn invalid_length(len: usize) -> Self { Error::InvalidLength(len) }
|
||||
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn unknown_variant(variant: &str) -> Self { Error::UnknownVariant(String::from(variant)) }
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn unknown_field(field: &str) -> Self { Error::UnknownField(String::from(field)) }
|
||||
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
fn unknown_variant(variant: &str) -> Self { Error::UnknownVariant("unknown variant") }
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
fn unknown_field(field: &str) -> Self { Error::UnknownField("unknown field") }
|
||||
fn missing_field(field: &'static str) -> Self { Error::MissingField(field) }
|
||||
#[cfg(not(any(feature = "std", feature = "collections")))]
|
||||
fn custom<T: Display>(msg: T) -> Self {
|
||||
Error(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
impl Display for Error {
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
match *self {
|
||||
Error::Custom(ref s) => write!(formatter, "{}", s),
|
||||
Error::EndOfStream => formatter.write_str("End of stream"),
|
||||
Error::InvalidType(ty) => write!(formatter, "Invalid type, expected `{:?}`", ty),
|
||||
Error::InvalidValue(ref value) => write!(formatter, "Invalid value: {}", value),
|
||||
Error::InvalidLength(len) => write!(formatter, "Invalid length: {}", len),
|
||||
Error::UnknownVariant(ref variant) => {
|
||||
write!(formatter, "Unknown variant: {}", variant)
|
||||
}
|
||||
Error::UnknownField(ref field) => write!(formatter, "Unknown field: {}", field),
|
||||
Error::MissingField(field) => write!(formatter, "Missing field: {}", field),
|
||||
}
|
||||
formatter.write_str(&self.0)
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "std", feature = "collections")))]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.write_str("Serde deserialization error")
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn description(&self) -> &str {
|
||||
"Serde Deserialization Error"
|
||||
&self.0
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
None
|
||||
#[cfg(not(any(feature = "std", feature = "collections")))]
|
||||
fn description(&self) -> &str {
|
||||
"Serde deserialization error"
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,10 +247,10 @@ impl<'a, E> de::EnumVisitor for StrDeserializer<'a, E>
|
||||
type Error = E;
|
||||
type Variant = private::UnitOnly<E>;
|
||||
|
||||
fn visit_variant<T>(self) -> Result<(T, Self::Variant), Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
de::Deserialize::deserialize(self).map(private::unit_only)
|
||||
seed.deserialize(self).map(private::unit_only)
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,10 +306,10 @@ impl<'a, E> de::EnumVisitor for StringDeserializer<E>
|
||||
type Error = E;
|
||||
type Variant = private::UnitOnly<E>;
|
||||
|
||||
fn visit_variant<T>(self) -> Result<(T, Self::Variant), Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
de::Deserialize::deserialize(self).map(private::unit_only)
|
||||
seed.deserialize(self).map(private::unit_only)
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,10 +368,10 @@ impl<'a, E> de::EnumVisitor for CowStrDeserializer<'a, E>
|
||||
type Error = E;
|
||||
type Variant = private::UnitOnly<E>;
|
||||
|
||||
fn visit_variant<T>(self) -> Result<(T, Self::Variant), Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
de::Deserialize::deserialize(self).map(private::unit_only)
|
||||
seed.deserialize(self).map(private::unit_only)
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,22 +379,37 @@ impl<'a, E> de::EnumVisitor for CowStrDeserializer<'a, E>
|
||||
|
||||
/// A helper deserializer that deserializes a sequence.
|
||||
pub struct SeqDeserializer<I, E> {
|
||||
iter: I,
|
||||
len: usize,
|
||||
iter: iter::Fuse<I>,
|
||||
count: usize,
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<I, E> SeqDeserializer<I, E>
|
||||
where E: de::Error,
|
||||
where I: Iterator,
|
||||
E: de::Error,
|
||||
{
|
||||
/// Construct a new `SeqDeserializer<I>`.
|
||||
pub fn new(iter: I, len: usize) -> Self {
|
||||
pub fn new(iter: I) -> Self {
|
||||
SeqDeserializer {
|
||||
iter: iter,
|
||||
len: len,
|
||||
iter: iter.fuse(),
|
||||
count: 0,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), E> {
|
||||
let mut remaining = 0;
|
||||
while self.iter.next().is_some() {
|
||||
remaining += 1;
|
||||
}
|
||||
if remaining == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
// First argument is the number of elements in the data, second
|
||||
// argument is the number of elements expected by the Deserialize.
|
||||
Err(de::Error::invalid_length(self.count + remaining, &ExpectedInSeq(self.count)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
|
||||
@ -459,11 +423,8 @@ impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
let v = try!(visitor.visit_seq(&mut self));
|
||||
if self.len == 0 {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err(de::Error::invalid_length(self.len))
|
||||
}
|
||||
try!(self.end());
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
forward_to_deserialize! {
|
||||
@ -480,20 +441,32 @@ impl<I, T, E> de::SeqVisitor for SeqDeserializer<I, E>
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn visit<V>(&mut self) -> Result<Option<V>, Self::Error>
|
||||
where V: de::Deserialize
|
||||
fn visit_seed<V>(&mut self, seed: V) -> Result<Option<V::Value>, Self::Error>
|
||||
where V: de::DeserializeSeed
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some(value) => {
|
||||
self.len -= 1;
|
||||
de::Deserialize::deserialize(value.into_deserializer()).map(Some)
|
||||
self.count += 1;
|
||||
seed.deserialize(value.into_deserializer()).map(Some)
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.len, Some(self.len))
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
struct ExpectedInSeq(usize);
|
||||
|
||||
impl Expected for ExpectedInSeq {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.0 == 1 {
|
||||
write!(formatter, "1 element in sequence")
|
||||
} else {
|
||||
write!(formatter, "{} elements in sequence", self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,8 +480,7 @@ impl<T, E> ValueDeserializer<E> for Vec<T>
|
||||
type Deserializer = SeqDeserializer<vec::IntoIter<T>, E>;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
let len = self.len();
|
||||
SeqDeserializer::new(self.into_iter(), len)
|
||||
SeqDeserializer::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,8 +492,7 @@ impl<T, E> ValueDeserializer<E> for BTreeSet<T>
|
||||
type Deserializer = SeqDeserializer<btree_set::IntoIter<T>, E>;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
let len = self.len();
|
||||
SeqDeserializer::new(self.into_iter(), len)
|
||||
SeqDeserializer::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
@ -533,8 +504,7 @@ impl<T, E> ValueDeserializer<E> for HashSet<T>
|
||||
type Deserializer = SeqDeserializer<hash_set::IntoIter<T>, E>;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
let len = self.len();
|
||||
SeqDeserializer::new(self.into_iter(), len)
|
||||
SeqDeserializer::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,66 +549,66 @@ impl<V_, E> de::Deserializer for SeqVisitorDeserializer<V_, E>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A helper deserializer that deserializes a map.
|
||||
pub struct MapDeserializer<I, K, V, E>
|
||||
where I: Iterator<Item=(K, V)>,
|
||||
K: ValueDeserializer<E>,
|
||||
V: ValueDeserializer<E>,
|
||||
pub struct MapDeserializer<I, E>
|
||||
where I: Iterator,
|
||||
I::Item: private::Pair,
|
||||
<I::Item as private::Pair>::First: ValueDeserializer<E>,
|
||||
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
|
||||
E: de::Error,
|
||||
{
|
||||
iter: I,
|
||||
value: Option<V>,
|
||||
len: Option<usize>,
|
||||
iter: iter::Fuse<I>,
|
||||
value: Option<<I::Item as private::Pair>::Second>,
|
||||
count: usize,
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<I, K, V, E> MapDeserializer<I, K, V, E>
|
||||
where I: Iterator<Item=(K, V)>,
|
||||
K: ValueDeserializer<E>,
|
||||
V: ValueDeserializer<E>,
|
||||
impl<I, E> MapDeserializer<I, E>
|
||||
where I: Iterator,
|
||||
I::Item: private::Pair,
|
||||
<I::Item as private::Pair>::First: ValueDeserializer<E>,
|
||||
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
|
||||
E: de::Error,
|
||||
{
|
||||
/// Construct a new `MapDeserializer<I, K, V, E>` with a specific length.
|
||||
pub fn new(iter: I, len: usize) -> Self {
|
||||
/// Construct a new `MapDeserializer<I, K, V, E>`.
|
||||
pub fn new(iter: I) -> Self {
|
||||
MapDeserializer {
|
||||
iter: iter,
|
||||
iter: iter.fuse(),
|
||||
value: None,
|
||||
len: Some(len),
|
||||
count: 0,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a new `MapDeserializer<I, K, V, E>` that is not bounded
|
||||
/// by a specific length and that delegates to `iter` for its size hint.
|
||||
pub fn unbounded(iter: I) -> Self {
|
||||
MapDeserializer {
|
||||
iter: iter,
|
||||
value: None,
|
||||
len: None,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) -> Option<(K, V)> {
|
||||
self.iter.next().map(|(k, v)| {
|
||||
if let Some(len) = self.len.as_mut() {
|
||||
*len -= 1;
|
||||
fn next(&mut self) -> Option<(<I::Item as private::Pair>::First, <I::Item as private::Pair>::Second)> {
|
||||
match self.iter.next() {
|
||||
Some(kv) => {
|
||||
self.count += 1;
|
||||
Some(private::Pair::split(kv))
|
||||
}
|
||||
(k, v)
|
||||
})
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), E> {
|
||||
match self.len {
|
||||
Some(len) if len > 0 => Err(de::Error::invalid_length(len)),
|
||||
_ => Ok(())
|
||||
let mut remaining = 0;
|
||||
while self.iter.next().is_some() {
|
||||
remaining += 1;
|
||||
}
|
||||
if remaining == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
// First argument is the number of elements in the data, second
|
||||
// argument is the number of elements expected by the Deserialize.
|
||||
Err(de::Error::invalid_length(self.count + remaining, &ExpectedInMap(self.count)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
|
||||
where I: Iterator<Item=(K, V)>,
|
||||
K: ValueDeserializer<E>,
|
||||
V: ValueDeserializer<E>,
|
||||
impl<I, E> de::Deserializer for MapDeserializer<I, E>
|
||||
where I: Iterator,
|
||||
I::Item: private::Pair,
|
||||
<I::Item as private::Pair>::First: ValueDeserializer<E>,
|
||||
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
|
||||
E: de::Error,
|
||||
{
|
||||
type Error = E;
|
||||
@ -659,17 +629,10 @@ impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn deserialize_seq_fixed_size<V_>(mut self, len: usize, visitor: V_) -> Result<V_::Value, Self::Error>
|
||||
fn deserialize_seq_fixed_size<V_>(self, _len: usize, visitor: V_) -> Result<V_::Value, Self::Error>
|
||||
where V_: de::Visitor,
|
||||
{
|
||||
match self.len {
|
||||
Some(map_len) if map_len != len => Err(de::Error::invalid_length(len)),
|
||||
_ => {
|
||||
let value = try!(visitor.visit_seq(&mut self));
|
||||
try!(self.end());
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
self.deserialize_seq(visitor)
|
||||
}
|
||||
|
||||
forward_to_deserialize! {
|
||||
@ -679,47 +642,45 @@ impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
|
||||
where I: Iterator<Item=(K, V)>,
|
||||
K: ValueDeserializer<E>,
|
||||
V: ValueDeserializer<E>,
|
||||
impl<I, E> de::MapVisitor for MapDeserializer<I, E>
|
||||
where I: Iterator,
|
||||
I::Item: private::Pair,
|
||||
<I::Item as private::Pair>::First: ValueDeserializer<E>,
|
||||
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
|
||||
E: de::Error,
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn visit_key<T>(&mut self) -> Result<Option<T>, Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
match self.next() {
|
||||
Some((key, value)) => {
|
||||
self.value = Some(value);
|
||||
de::Deserialize::deserialize(key.into_deserializer()).map(Some)
|
||||
seed.deserialize(key.into_deserializer()).map(Some)
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<T>(&mut self) -> Result<T, Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
match self.value.take() {
|
||||
Some(value) => {
|
||||
de::Deserialize::deserialize(value.into_deserializer())
|
||||
}
|
||||
None => {
|
||||
Err(de::Error::end_of_stream())
|
||||
}
|
||||
}
|
||||
let value = self.value.take();
|
||||
// Panic because this indicates a bug in the program rather than an
|
||||
// expected failure.
|
||||
let value = value.expect("MapVisitor::visit_value called before visit_key");
|
||||
seed.deserialize(value.into_deserializer())
|
||||
}
|
||||
|
||||
fn visit<TK, TV>(&mut self) -> Result<Option<(TK, TV)>, Self::Error>
|
||||
where TK: de::Deserialize,
|
||||
TV: de::Deserialize
|
||||
fn visit_seed<TK, TV>(&mut self, kseed: TK, vseed: TV) -> Result<Option<(TK::Value, TV::Value)>, Self::Error>
|
||||
where TK: de::DeserializeSeed,
|
||||
TV: de::DeserializeSeed
|
||||
{
|
||||
match self.next() {
|
||||
Some((key, value)) => {
|
||||
let key = try!(de::Deserialize::deserialize(key.into_deserializer()));
|
||||
let value = try!(de::Deserialize::deserialize(value.into_deserializer()));
|
||||
let key = try!(kseed.deserialize(key.into_deserializer()));
|
||||
let value = try!(vseed.deserialize(value.into_deserializer()));
|
||||
Ok(Some((key, value)))
|
||||
}
|
||||
None => Ok(None)
|
||||
@ -727,34 +688,33 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.len.map_or_else(
|
||||
|| self.iter.size_hint(),
|
||||
|len| (len, Some(len)))
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, K, V, E> de::SeqVisitor for MapDeserializer<I, K, V, E>
|
||||
where I: Iterator<Item=(K, V)>,
|
||||
K: ValueDeserializer<E>,
|
||||
V: ValueDeserializer<E>,
|
||||
impl<I, E> de::SeqVisitor for MapDeserializer<I, E>
|
||||
where I: Iterator,
|
||||
I::Item: private::Pair,
|
||||
<I::Item as private::Pair>::First: ValueDeserializer<E>,
|
||||
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
|
||||
E: de::Error,
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
match self.next() {
|
||||
Some((k, v)) => {
|
||||
let de = PairDeserializer(k, v, PhantomData);
|
||||
de::Deserialize::deserialize(de).map(Some)
|
||||
seed.deserialize(de).map(Some)
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
de::MapVisitor::size_hint(self)
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
@ -789,7 +749,10 @@ impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
|
||||
if pair_visitor.1.is_none() {
|
||||
Ok(pair)
|
||||
} else {
|
||||
Err(de::Error::invalid_length(pair_visitor.size_hint().0))
|
||||
let remaining = pair_visitor.size_hint().0;
|
||||
// First argument is the number of elements in the data, second
|
||||
// argument is the number of elements expected by the Deserialize.
|
||||
Err(de::Error::invalid_length(2, &ExpectedInSeq(2 - remaining)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,7 +762,9 @@ impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
|
||||
if len == 2 {
|
||||
self.deserialize_seq(visitor)
|
||||
} else {
|
||||
Err(de::Error::invalid_length(len))
|
||||
// First argument is the number of elements in the data, second
|
||||
// argument is the number of elements expected by the Deserialize.
|
||||
Err(de::Error::invalid_length(2, &ExpectedInSeq(len)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -813,13 +778,13 @@ impl<A, B, E> de::SeqVisitor for PairVisitor<A, B, E>
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
if let Some(k) = self.0.take() {
|
||||
de::Deserialize::deserialize(k.into_deserializer()).map(Some)
|
||||
seed.deserialize(k.into_deserializer()).map(Some)
|
||||
} else if let Some(v) = self.1.take() {
|
||||
de::Deserialize::deserialize(v.into_deserializer()).map(Some)
|
||||
seed.deserialize(v.into_deserializer()).map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@ -837,6 +802,18 @@ impl<A, B, E> de::SeqVisitor for PairVisitor<A, B, E>
|
||||
}
|
||||
}
|
||||
|
||||
struct ExpectedInMap(usize);
|
||||
|
||||
impl Expected for ExpectedInMap {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.0 == 1 {
|
||||
write!(formatter, "1 element in map")
|
||||
} else {
|
||||
write!(formatter, "{} elements in map", self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
@ -845,11 +822,10 @@ impl<K, V, E> ValueDeserializer<E> for BTreeMap<K, V>
|
||||
V: ValueDeserializer<E>,
|
||||
E: de::Error,
|
||||
{
|
||||
type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V, E>;
|
||||
type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, E>;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
let len = self.len();
|
||||
MapDeserializer::new(self.into_iter(), len)
|
||||
MapDeserializer::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
@ -859,11 +835,10 @@ impl<K, V, E> ValueDeserializer<E> for HashMap<K, V>
|
||||
V: ValueDeserializer<E>,
|
||||
E: de::Error,
|
||||
{
|
||||
type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V, E>;
|
||||
type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, E>;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
let len = self.len();
|
||||
MapDeserializer::new(self.into_iter(), len)
|
||||
MapDeserializer::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
@ -977,7 +952,7 @@ impl<E> de::Deserializer for ByteBufDeserializer<E>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod private {
|
||||
use de;
|
||||
use de::{self, Unexpected};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
pub struct UnitOnly<E>(PhantomData<E>);
|
||||
@ -995,10 +970,10 @@ mod private {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_newtype<T>(self) -> Result<T, Self::Error>
|
||||
where T: de::Deserialize,
|
||||
fn visit_newtype_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
Err(de::Error::invalid_type(de::Type::NewtypeVariant))
|
||||
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant"))
|
||||
}
|
||||
|
||||
fn visit_tuple<V>(self,
|
||||
@ -1006,7 +981,7 @@ mod private {
|
||||
_visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor
|
||||
{
|
||||
Err(de::Error::invalid_type(de::Type::TupleVariant))
|
||||
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"))
|
||||
}
|
||||
|
||||
fn visit_struct<V>(self,
|
||||
@ -1014,7 +989,21 @@ mod private {
|
||||
_visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: de::Visitor
|
||||
{
|
||||
Err(de::Error::invalid_type(de::Type::StructVariant))
|
||||
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Avoid having to restate the generic types on MapDeserializer. The
|
||||
/// Iterator::Item contains enough information to figure out K and V.
|
||||
pub trait Pair {
|
||||
type First;
|
||||
type Second;
|
||||
fn split(self) -> (Self::First, Self::Second);
|
||||
}
|
||||
|
||||
impl<A, B> Pair for (A, B) {
|
||||
type First = A;
|
||||
type Second = B;
|
||||
fn split(self) -> (A, B) { self }
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
//! A stand-in for `std::error`
|
||||
use core::any::TypeId;
|
||||
use core::fmt::{Debug, Display};
|
||||
|
||||
/// A stand-in for `std::error::Error`, which requires no allocation.
|
||||
@ -13,10 +12,4 @@ pub trait Error: Debug + Display {
|
||||
|
||||
/// The lower-level cause of this error, if any.
|
||||
fn cause(&self) -> Option<&Error> { None }
|
||||
|
||||
/// Get the `TypeId` of `self`
|
||||
#[doc(hidden)]
|
||||
fn type_id(&self) -> TypeId where Self: 'static {
|
||||
TypeId::of::<Self>()
|
||||
}
|
||||
}
|
||||
|
@ -40,11 +40,6 @@ mod core {
|
||||
pub use ser::{Serialize, Serializer};
|
||||
pub use de::{Deserialize, Deserializer};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
macro_rules! format {
|
||||
($s:expr, $($rest:tt)*) => ($s)
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
|
@ -772,7 +772,7 @@ impl Serialize for path::Path {
|
||||
{
|
||||
match self.to_str() {
|
||||
Some(s) => s.serialize(serializer),
|
||||
None => Err(Error::invalid_value("Path contains invalid UTF-8 characters")),
|
||||
None => Err(Error::custom("Path contains invalid UTF-8 characters")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ use core::marker::PhantomData;
|
||||
#[cfg(feature = "unstable")]
|
||||
use core::cell::RefCell;
|
||||
|
||||
use core::fmt::Display;
|
||||
|
||||
pub mod impls;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -31,17 +33,7 @@ pub mod impls;
|
||||
/// `Serializer` error.
|
||||
pub trait Error: Sized + error::Error {
|
||||
/// Raised when there is a general error when serializing a type.
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn custom<T: Into<String>>(msg: T) -> Self;
|
||||
|
||||
/// Raised when there is a general error when serializing a type.
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
fn custom<T: Into<&'static str>>(msg: T) -> Self;
|
||||
|
||||
/// Raised when a `Serialize` was passed an incorrect value.
|
||||
fn invalid_value(msg: &str) -> Self {
|
||||
Error::custom(format!("invalid value: {}", msg))
|
||||
}
|
||||
fn custom<T: Display>(msg: T) -> Self;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_codegen"
|
||||
version = "0.9.0-rc1"
|
||||
version = "0.9.0-rc2"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
|
@ -200,12 +200,18 @@ fn deserialize_unit_struct(
|
||||
) -> Tokens {
|
||||
let type_name = item_attrs.name().deserialize_name();
|
||||
|
||||
let expecting = format!("unit struct {}", type_ident);
|
||||
|
||||
quote!({
|
||||
struct __Visitor;
|
||||
|
||||
impl _serde::de::Visitor for __Visitor {
|
||||
type Value = #type_ident;
|
||||
|
||||
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
formatter.write_str(#expecting)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<__E>(self) -> ::std::result::Result<#type_ident, __E>
|
||||
where __E: _serde::de::Error,
|
||||
@ -242,6 +248,10 @@ fn deserialize_tuple(
|
||||
Some(variant_ident) => quote!(#type_ident::#variant_ident),
|
||||
None => quote!(#type_ident),
|
||||
};
|
||||
let expecting = match variant_ident {
|
||||
Some(variant_ident) => format!("tuple variant {}::{}", type_ident, variant_ident),
|
||||
None => format!("tuple struct {}", type_ident),
|
||||
};
|
||||
|
||||
let nfields = fields.len();
|
||||
|
||||
@ -287,6 +297,10 @@ fn deserialize_tuple(
|
||||
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
||||
type Value = #ty;
|
||||
|
||||
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
formatter.write_str(#expecting)
|
||||
}
|
||||
|
||||
#visit_newtype_struct
|
||||
|
||||
#[inline]
|
||||
@ -310,6 +324,11 @@ fn deserialize_seq(
|
||||
) -> Tokens {
|
||||
let vars = (0..fields.len()).map(field_i as fn(_) -> _);
|
||||
|
||||
let deserialized_count = fields.iter()
|
||||
.filter(|field| !field.attrs.skip_deserializing())
|
||||
.count();
|
||||
let expecting = format!("tuple of {} elements", deserialized_count);
|
||||
|
||||
let mut index_in_seq = 0usize;
|
||||
let let_values = vars.clone().zip(fields)
|
||||
.map(|(var, field)| {
|
||||
@ -338,7 +357,7 @@ fn deserialize_seq(
|
||||
let #var = match #visit {
|
||||
Some(value) => { value },
|
||||
None => {
|
||||
return Err(_serde::de::Error::invalid_length(#index_in_seq));
|
||||
return Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -413,6 +432,10 @@ fn deserialize_struct(
|
||||
Some(variant_ident) => quote!(#type_ident::#variant_ident),
|
||||
None => quote!(#type_ident),
|
||||
};
|
||||
let expecting = match variant_ident {
|
||||
Some(variant_ident) => format!("struct variant {}::{}", type_ident, variant_ident),
|
||||
None => format!("struct {}", type_ident),
|
||||
};
|
||||
|
||||
let visit_seq = deserialize_seq(
|
||||
type_ident,
|
||||
@ -457,6 +480,10 @@ fn deserialize_struct(
|
||||
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
||||
type Value = #ty;
|
||||
|
||||
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
formatter.write_str(#expecting)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<__V>(self, #visitor_var: __V) -> ::std::result::Result<#ty, __V::Error>
|
||||
where __V: _serde::de::SeqVisitor
|
||||
@ -489,24 +516,27 @@ fn deserialize_item_enum(
|
||||
|
||||
let type_name = item_attrs.name().deserialize_name();
|
||||
|
||||
let variant_names_idents = variants.iter()
|
||||
let expecting = format!("enum {}", type_ident);
|
||||
|
||||
let variant_names_idents: Vec<_> = variants.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
||||
.collect();
|
||||
|
||||
let variants_stmt = {
|
||||
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
|
||||
quote! {
|
||||
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
|
||||
}
|
||||
};
|
||||
|
||||
let variant_visitor = deserialize_field_visitor(
|
||||
variant_names_idents,
|
||||
item_attrs,
|
||||
true,
|
||||
);
|
||||
|
||||
let variant_names = variants.iter().map(|variant| variant.attrs.name().deserialize_name());
|
||||
|
||||
let variants_stmt = quote! {
|
||||
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
|
||||
};
|
||||
|
||||
// Match arms to extract a variant from a string
|
||||
let variant_arms = variants.iter()
|
||||
.enumerate()
|
||||
@ -555,6 +585,10 @@ fn deserialize_item_enum(
|
||||
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
||||
type Value = #ty;
|
||||
|
||||
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
formatter.write_str(#expecting)
|
||||
}
|
||||
|
||||
fn visit_enum<__V>(self, visitor: __V) -> ::std::result::Result<#ty, __V::Error>
|
||||
where __V: _serde::de::EnumVisitor,
|
||||
{
|
||||
@ -660,7 +694,7 @@ fn deserialize_field_visitor(
|
||||
|
||||
let visit_usize = if is_variant {
|
||||
let variant_indices = 0usize..;
|
||||
let fallthrough_msg = format!("expected variant index 0 <= i < {}", fields.len());
|
||||
let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len());
|
||||
Some(quote! {
|
||||
fn visit_usize<__E>(self, value: usize) -> ::std::result::Result<__Field, __E>
|
||||
where __E: _serde::de::Error
|
||||
@ -669,7 +703,9 @@ fn deserialize_field_visitor(
|
||||
#(
|
||||
#variant_indices => Ok(__Field::#field_idents),
|
||||
)*
|
||||
_ => Err(_serde::de::Error::invalid_value(#fallthrough_msg))
|
||||
_ => Err(_serde::de::Error::invalid_value(
|
||||
_serde::de::Unexpected::Unsigned(value as u64),
|
||||
&#fallthrough_msg))
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -679,11 +715,11 @@ fn deserialize_field_visitor(
|
||||
|
||||
let fallthrough_arm = if is_variant {
|
||||
quote! {
|
||||
Err(_serde::de::Error::unknown_variant(value))
|
||||
Err(_serde::de::Error::unknown_variant(value, VARIANTS))
|
||||
}
|
||||
} else if item_attrs.deny_unknown_fields() {
|
||||
quote! {
|
||||
Err(_serde::de::Error::unknown_field(value))
|
||||
Err(_serde::de::Error::unknown_field(value, FIELDS))
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
@ -718,6 +754,10 @@ fn deserialize_field_visitor(
|
||||
impl _serde::de::Visitor for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
|
||||
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
formatter.write_str("field name")
|
||||
}
|
||||
|
||||
#visit_usize
|
||||
|
||||
fn visit_str<__E>(self, value: &str) -> ::std::result::Result<__Field, __E>
|
||||
@ -759,12 +799,19 @@ fn deserialize_struct_visitor(
|
||||
fields: &[Field],
|
||||
item_attrs: &attr::Item,
|
||||
) -> (Tokens, Tokens, Tokens) {
|
||||
let field_names_idents = fields.iter()
|
||||
let field_names_idents: Vec<_> = fields.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
||||
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
|
||||
.collect();
|
||||
|
||||
let fields_stmt = {
|
||||
let field_names = field_names_idents.iter().map(|&(ref name, _)| name);
|
||||
quote! {
|
||||
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
|
||||
}
|
||||
};
|
||||
|
||||
let field_visitor = deserialize_field_visitor(
|
||||
field_names_idents,
|
||||
item_attrs,
|
||||
@ -779,11 +826,6 @@ fn deserialize_struct_visitor(
|
||||
item_attrs,
|
||||
);
|
||||
|
||||
let field_names = fields.iter().map(|field| field.attrs.name().deserialize_name());
|
||||
let fields_stmt = quote! {
|
||||
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
|
||||
};
|
||||
|
||||
(field_visitor, fields_stmt, visit_map)
|
||||
}
|
||||
|
||||
@ -974,7 +1016,7 @@ fn expr_is_missing(attrs: &attr::Field) -> Tokens {
|
||||
match attrs.deserialize_with() {
|
||||
None => {
|
||||
quote! {
|
||||
try!(visitor.missing_field(#name))
|
||||
try!(_serde::de::private::missing_field(#name))
|
||||
}
|
||||
}
|
||||
Some(_) => {
|
||||
|
@ -257,10 +257,10 @@ fn serialize_variant(
|
||||
let variant_name = variant.attrs.name().serialize_name();
|
||||
|
||||
if variant.attrs.skip_serializing() {
|
||||
let skipped_msg = format!("The enum variant {}::{} cannot be serialized",
|
||||
let skipped_msg = format!("the enum variant {}::{} cannot be serialized",
|
||||
type_ident, variant_ident);
|
||||
let skipped_err = quote! {
|
||||
Err(_serde::ser::Error::invalid_value(#skipped_msg))
|
||||
Err(_serde::ser::Error::custom(#skipped_msg))
|
||||
};
|
||||
let fields_pat = match variant.style {
|
||||
Style::Unit => quote!(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_derive"
|
||||
version = "0.9.0-rc1"
|
||||
version = "0.9.0-rc2"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||
@ -15,7 +15,7 @@ name = "serde_derive"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies.serde_codegen]
|
||||
version = "=0.9.0-rc1"
|
||||
version = "=0.9.0-rc2"
|
||||
path = "../serde_codegen"
|
||||
default-features = false
|
||||
features = ["with-syn"]
|
||||
@ -23,5 +23,5 @@ features = ["with-syn"]
|
||||
[dev-dependencies]
|
||||
compiletest_rs = "^0.2.0"
|
||||
fnv = "1.0"
|
||||
serde = { version = "0.9.0-rc1", path = "../serde" }
|
||||
serde_test = { version = "0.9.0-rc1", path = "../serde_test" }
|
||||
serde = { version = "0.9.0-rc2", path = "../serde" }
|
||||
serde_test = { version = "0.9.0-rc2", path = "../serde_test" }
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_test"
|
||||
version = "0.9.0-rc1"
|
||||
version = "0.9.0-rc2"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||
@ -12,4 +12,4 @@ keywords = ["serde", "serialization"]
|
||||
include = ["Cargo.toml", "src/**/*.rs"]
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "0.9.0-rc1", path = "../serde" }
|
||||
serde = { version = "0.9.0-rc2", path = "../serde" }
|
||||
|
@ -3,6 +3,7 @@ use std::iter;
|
||||
use serde::de::{
|
||||
self,
|
||||
Deserialize,
|
||||
DeserializeSeed,
|
||||
EnumVisitor,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
@ -42,7 +43,7 @@ impl<I> Deserializer<I>
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +259,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
Some(Token::Option(false)) => visitor.visit_none(),
|
||||
Some(Token::Option(true)) => visitor.visit_some(self),
|
||||
Some(Token::Unit) => visitor.visit_unit(),
|
||||
Some(Token::UnitStruct(name)) => visitor.visit_unit_struct(name),
|
||||
Some(Token::UnitStruct(_name)) => visitor.visit_unit(),
|
||||
Some(Token::SeqStart(len)) => {
|
||||
self.visit_seq(len, visitor)
|
||||
}
|
||||
@ -272,7 +273,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
self.visit_map(Some(len), visitor)
|
||||
}
|
||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,7 +296,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
visitor.visit_none()
|
||||
}
|
||||
Some(_) => visitor.visit_some(self),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +326,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
let token = self.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => { return Err(Error::EndOfStream); }
|
||||
None => { return Err(Error::EndOfTokens); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,7 +343,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
}
|
||||
}
|
||||
Some(_) => self.deserialize(visitor),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,7 +362,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
}
|
||||
}
|
||||
Some(_) => self.deserialize(visitor),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,7 +377,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
self.visit_array(len, visitor)
|
||||
}
|
||||
Some(_) => self.deserialize(visitor),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,7 +412,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
self.visit_tuple_struct(len, visitor)
|
||||
}
|
||||
Some(_) => self.deserialize(visitor),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +456,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
}
|
||||
}
|
||||
Some(_) => self.deserialize(visitor),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,7 +480,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||
self.visit_map(Some(fields.len()), visitor)
|
||||
}
|
||||
Some(_) => self.deserialize(visitor),
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -496,21 +497,21 @@ impl<'a, I> SeqVisitor for DeserializerSeqVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: Deserialize,
|
||||
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||
where T: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::SeqSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| len - 1);
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::SeqEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,21 +533,21 @@ impl<'a, I> SeqVisitor for DeserializerArrayVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: Deserialize,
|
||||
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||
where T: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::SeqSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len -= 1;
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::SeqEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -567,21 +568,21 @@ impl<'a, I> SeqVisitor for DeserializerTupleVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: Deserialize,
|
||||
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||
where T: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::TupleSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len -= 1;
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::TupleEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,21 +603,21 @@ impl<'a, I> SeqVisitor for DeserializerTupleStructVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: Deserialize,
|
||||
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||
where T: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::TupleStructSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len -= 1;
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::TupleStructEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -637,21 +638,21 @@ impl<'a, I> SeqVisitor for DeserializerVariantSeqVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: Deserialize,
|
||||
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||
where T: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumSeqSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| len - 1);
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::EnumSeqEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -673,28 +674,28 @@ impl<'a, I> MapVisitor for DeserializerMapVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: Deserialize,
|
||||
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where K: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::MapSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::MapEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: Deserialize,
|
||||
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where V: DeserializeSeed,
|
||||
{
|
||||
Deserialize::deserialize(&mut *self.de)
|
||||
seed.deserialize(&mut *self.de)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
@ -715,28 +716,28 @@ impl<'a, I> MapVisitor for DeserializerStructVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: Deserialize,
|
||||
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where K: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::StructSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.saturating_sub(1);
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::StructEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: Deserialize,
|
||||
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where V: DeserializeSeed,
|
||||
{
|
||||
Deserialize::deserialize(&mut *self.de)
|
||||
seed.deserialize(&mut *self.de)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
@ -756,8 +757,8 @@ impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I>
|
||||
type Error = Error;
|
||||
type Variant = Self;
|
||||
|
||||
fn visit_variant<V>(self) -> Result<(V, Self), Error>
|
||||
where V: Deserialize,
|
||||
fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self), Error>
|
||||
where V: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumUnit(_, v))
|
||||
@ -765,14 +766,14 @@ impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I>
|
||||
| Some(&Token::EnumSeqStart(_, v, _))
|
||||
| Some(&Token::EnumMapStart(_, v, _)) => {
|
||||
let de = v.into_deserializer();
|
||||
let value = try!(Deserialize::deserialize(de));
|
||||
let value = try!(seed.deserialize(de));
|
||||
Ok((value, self))
|
||||
}
|
||||
Some(_) => {
|
||||
let value = try!(Deserialize::deserialize(&mut *self.de));
|
||||
let value = try!(seed.deserialize(&mut *self.de));
|
||||
Ok((value, self))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -791,22 +792,22 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
|
||||
Some(_) => {
|
||||
Deserialize::deserialize(self.de)
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_newtype<T>(self) -> Result<T, Self::Error>
|
||||
where T: Deserialize,
|
||||
fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where T: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumNewType(_, _)) => {
|
||||
self.de.tokens.next();
|
||||
Deserialize::deserialize(self.de)
|
||||
seed.deserialize(self.de)
|
||||
}
|
||||
Some(_) => {
|
||||
Deserialize::deserialize(self.de)
|
||||
seed.deserialize(self.de)
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -837,7 +838,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
|
||||
Some(_) => {
|
||||
de::Deserializer::deserialize(self.de, visitor)
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -868,7 +869,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
|
||||
Some(_) => {
|
||||
de::Deserializer::deserialize(self.de, visitor)
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -885,28 +886,28 @@ impl<'a, I> MapVisitor for DeserializerVariantMapVisitor<'a, I>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: Deserialize,
|
||||
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where K: DeserializeSeed,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumMapSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
||||
Deserialize::deserialize(&mut *self.de).map(Some)
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
Some(&Token::EnumMapEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: Deserialize,
|
||||
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where V: DeserializeSeed,
|
||||
{
|
||||
Deserialize::deserialize(&mut *self.de)
|
||||
seed.deserialize(&mut *self.de)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::{error, fmt};
|
||||
use std::error;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
use serde::{ser, de};
|
||||
|
||||
@ -6,82 +7,42 @@ use token::Token;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum Error {
|
||||
// Shared
|
||||
Custom(String),
|
||||
InvalidValue(String),
|
||||
|
||||
// De
|
||||
EndOfStream,
|
||||
InvalidType(de::Type),
|
||||
InvalidLength(usize),
|
||||
UnknownVariant(String),
|
||||
UnknownField(String),
|
||||
MissingField(&'static str),
|
||||
DuplicateField(&'static str),
|
||||
Message(String),
|
||||
InvalidName(&'static str),
|
||||
UnexpectedToken(Token<'static>),
|
||||
EndOfTokens,
|
||||
}
|
||||
|
||||
impl ser::Error for Error {
|
||||
fn custom<T: Into<String>>(msg: T) -> Error {
|
||||
Error::Custom(msg.into())
|
||||
}
|
||||
|
||||
fn invalid_value(msg: &str) -> Error {
|
||||
Error::InvalidValue(msg.to_owned())
|
||||
fn custom<T: Display>(msg: T) -> Error {
|
||||
Error::Message(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Error for Error {
|
||||
fn custom<T: Into<String>>(msg: T) -> Error {
|
||||
Error::Custom(msg.into())
|
||||
}
|
||||
|
||||
fn end_of_stream() -> Error {
|
||||
Error::EndOfStream
|
||||
}
|
||||
|
||||
fn invalid_type(ty: de::Type) -> Error {
|
||||
Error::InvalidType(ty)
|
||||
}
|
||||
|
||||
fn invalid_value(msg: &str) -> Error {
|
||||
Error::InvalidValue(msg.to_owned())
|
||||
}
|
||||
|
||||
fn invalid_length(len: usize) -> Error {
|
||||
Error::InvalidLength(len)
|
||||
}
|
||||
|
||||
fn unknown_variant(variant: &str) -> Error {
|
||||
Error::UnknownVariant(variant.to_owned())
|
||||
}
|
||||
|
||||
fn unknown_field(field: &str) -> Error {
|
||||
Error::UnknownField(field.to_owned())
|
||||
}
|
||||
|
||||
fn missing_field(field: &'static str) -> Error {
|
||||
Error::MissingField(field)
|
||||
}
|
||||
|
||||
fn duplicate_field(field: &'static str) -> Error {
|
||||
Error::DuplicateField(field)
|
||||
fn custom<T: Display>(msg: T) -> Error {
|
||||
Error::Message(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.write_str(format!("{:?}", self).as_ref())
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Message(ref msg) => formatter.write_str(msg),
|
||||
Error::InvalidName(name) => write!(formatter, "invalid name `{}`", name),
|
||||
Error::UnexpectedToken(_) => formatter.write_str("unexpected token"),
|
||||
Error::EndOfTokens => formatter.write_str("end of tokens"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"Serde Error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
None
|
||||
match *self {
|
||||
Error::Message(ref msg) => msg,
|
||||
Error::InvalidName(_) => "invalid name",
|
||||
Error::UnexpectedToken(_) => "unexpected token",
|
||||
Error::EndOfTokens => "end of tokens",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_testing"
|
||||
version = "0.9.0-rc1"
|
||||
version = "0.9.0-rc2"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
|
@ -145,7 +145,7 @@ fn test_default_enum() {
|
||||
assert_de_tokens(
|
||||
&DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
|
||||
&[
|
||||
Token::EnumMapStart("DefaultEnum", "Struct", 5),
|
||||
Token::EnumMapStart("DefaultEnum", "Struct", 3),
|
||||
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a1"),
|
||||
@ -174,7 +174,7 @@ fn test_default_enum() {
|
||||
assert_de_tokens(
|
||||
&DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
|
||||
&[
|
||||
Token::EnumMapStart("DefaultEnum", "Struct", 5),
|
||||
Token::EnumMapStart("DefaultEnum", "Struct", 3),
|
||||
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a1"),
|
||||
@ -343,7 +343,7 @@ fn test_ignore_unknown() {
|
||||
Token::StructSep,
|
||||
Token::Str("whoops"),
|
||||
],
|
||||
Error::UnknownField("whoops".to_owned())
|
||||
Error::Message("unknown field `whoops`, expected `a1`".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
@ -905,7 +905,7 @@ fn test_missing_renamed_field_struct() {
|
||||
|
||||
Token::StructEnd,
|
||||
],
|
||||
Error::MissingField("a3"),
|
||||
Error::Message("missing field `a3`".to_owned()),
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
|
||||
@ -918,7 +918,7 @@ fn test_missing_renamed_field_struct() {
|
||||
|
||||
Token::StructEnd,
|
||||
],
|
||||
Error::MissingField("a5"),
|
||||
Error::Message("missing field `a5`".to_owned()),
|
||||
);
|
||||
}
|
||||
|
||||
@ -930,7 +930,7 @@ fn test_missing_renamed_field_enum() {
|
||||
|
||||
Token::EnumMapEnd,
|
||||
],
|
||||
Error::MissingField("b"),
|
||||
Error::Message("missing field `b`".to_owned()),
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
|
||||
@ -943,7 +943,7 @@ fn test_missing_renamed_field_enum() {
|
||||
|
||||
Token::EnumMapEnd,
|
||||
],
|
||||
Error::MissingField("d"),
|
||||
Error::Message("missing field `d`".to_owned()),
|
||||
);
|
||||
}
|
||||
|
||||
@ -962,7 +962,7 @@ fn test_invalid_length_enum() {
|
||||
Token::I32(1),
|
||||
Token::EnumSeqEnd,
|
||||
],
|
||||
Error::InvalidLength(1),
|
||||
Error::Message("invalid length 1, expected tuple of 3 elements".to_owned()),
|
||||
);
|
||||
assert_de_tokens_error::<InvalidLengthEnum>(
|
||||
&[
|
||||
@ -971,6 +971,6 @@ fn test_invalid_length_enum() {
|
||||
Token::I32(1),
|
||||
Token::EnumSeqEnd,
|
||||
],
|
||||
Error::InvalidLength(1),
|
||||
Error::Message("invalid length 1, expected tuple of 2 elements".to_owned()),
|
||||
);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::net;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use serde::de::Deserialize;
|
||||
use serde::Deserialize;
|
||||
|
||||
extern crate fnv;
|
||||
use self::fnv::FnvHasher;
|
||||
@ -863,7 +863,7 @@ declare_error_tests! {
|
||||
Token::StructSep,
|
||||
Token::Str("d"),
|
||||
],
|
||||
Error::UnknownField("d".to_owned()),
|
||||
Error::Message("unknown field `d`, expected `a`".to_owned()),
|
||||
}
|
||||
test_skipped_field_is_unknown<StructDenyUnknown> {
|
||||
&[
|
||||
@ -871,7 +871,7 @@ declare_error_tests! {
|
||||
Token::StructSep,
|
||||
Token::Str("b"),
|
||||
],
|
||||
Error::UnknownField("b".to_owned()),
|
||||
Error::Message("unknown field `b`, expected `a`".to_owned()),
|
||||
}
|
||||
test_skip_all_deny_unknown<StructSkipAllDenyUnknown> {
|
||||
&[
|
||||
@ -879,25 +879,25 @@ declare_error_tests! {
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
],
|
||||
Error::UnknownField("a".to_owned()),
|
||||
Error::Message("unknown field `a`, there are no fields".to_owned()),
|
||||
}
|
||||
test_unknown_variant<Enum> {
|
||||
&[
|
||||
Token::EnumUnit("Enum", "Foo"),
|
||||
],
|
||||
Error::UnknownVariant("Foo".to_owned()),
|
||||
Error::Message("unknown variant `Foo`, expected one of `Unit`, `Simple`, `Seq`, `Map`".to_owned()),
|
||||
}
|
||||
test_enum_skipped_variant<Enum> {
|
||||
&[
|
||||
Token::EnumUnit("Enum", "Skipped"),
|
||||
],
|
||||
Error::UnknownVariant("Skipped".to_owned()),
|
||||
Error::Message("unknown variant `Skipped`, expected one of `Unit`, `Simple`, `Seq`, `Map`".to_owned()),
|
||||
}
|
||||
test_enum_skip_all<EnumSkipAll> {
|
||||
&[
|
||||
Token::EnumUnit("EnumSkipAll", "Skipped"),
|
||||
],
|
||||
Error::UnknownVariant("Skipped".to_owned()),
|
||||
Error::Message("unknown variant `Skipped`, there are no variants".to_owned()),
|
||||
}
|
||||
test_struct_seq_too_long<Struct> {
|
||||
&[
|
||||
@ -918,7 +918,7 @@ declare_error_tests! {
|
||||
Token::MapSep,
|
||||
Token::Str("a"),
|
||||
],
|
||||
Error::DuplicateField("a"),
|
||||
Error::Message("duplicate field `a`".to_owned()),
|
||||
}
|
||||
test_duplicate_field_enum<Enum> {
|
||||
&[
|
||||
@ -930,7 +930,7 @@ declare_error_tests! {
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
],
|
||||
Error::DuplicateField("a"),
|
||||
Error::Message("duplicate field `a`".to_owned()),
|
||||
}
|
||||
test_enum_out_of_range<Enum> {
|
||||
&[
|
||||
@ -938,6 +938,6 @@ declare_error_tests! {
|
||||
Token::Usize(4),
|
||||
Token::Unit,
|
||||
],
|
||||
Error::InvalidValue("expected variant index 0 <= i < 4".to_owned()),
|
||||
Error::Message("invalid value: integer `4`, expected variant index 0 <= i < 4".into()),
|
||||
}
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ fn test_cannot_serialize_paths() {
|
||||
assert_ser_tokens_error(
|
||||
&Path::new(path),
|
||||
&[],
|
||||
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
|
||||
Error::Message("Path contains invalid UTF-8 characters".to_owned()));
|
||||
|
||||
let mut path_buf = PathBuf::new();
|
||||
path_buf.push(path);
|
||||
@ -440,7 +440,7 @@ fn test_cannot_serialize_paths() {
|
||||
assert_ser_tokens_error(
|
||||
&path_buf,
|
||||
&[],
|
||||
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
|
||||
Error::Message("Path contains invalid UTF-8 characters".to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -448,17 +448,17 @@ fn test_enum_skipped() {
|
||||
assert_ser_tokens_error(
|
||||
&Enum::SkippedUnit,
|
||||
&[],
|
||||
Error::InvalidValue("The enum variant Enum::SkippedUnit cannot be serialized".to_owned()));
|
||||
Error::Message("the enum variant Enum::SkippedUnit cannot be serialized".to_owned()));
|
||||
assert_ser_tokens_error(
|
||||
&Enum::SkippedOne(42),
|
||||
&[],
|
||||
Error::InvalidValue("The enum variant Enum::SkippedOne cannot be serialized".to_owned()));
|
||||
Error::Message("the enum variant Enum::SkippedOne cannot be serialized".to_owned()));
|
||||
assert_ser_tokens_error(
|
||||
&Enum::SkippedSeq(1, 2),
|
||||
&[],
|
||||
Error::InvalidValue("The enum variant Enum::SkippedSeq cannot be serialized".to_owned()));
|
||||
Error::Message("the enum variant Enum::SkippedSeq cannot be serialized".to_owned()));
|
||||
assert_ser_tokens_error(
|
||||
&Enum::SkippedMap { _a: 1, _b: 2 },
|
||||
&[],
|
||||
Error::InvalidValue("The enum variant Enum::SkippedMap cannot be serialized".to_owned()));
|
||||
Error::Message("the enum variant Enum::SkippedMap cannot be serialized".to_owned()));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user