Errors
This commit is contained in:
parent
d1325862f7
commit
a4126e4c5a
@ -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")]
|
||||
@ -69,7 +70,7 @@ use de::{
|
||||
Error,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
Type,
|
||||
Unexpected,
|
||||
VariantVisitor,
|
||||
Visitor,
|
||||
};
|
||||
@ -83,6 +84,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 +117,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 +133,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 +149,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 +227,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 +243,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 +268,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 +295,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, &self)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +304,7 @@ impl Visitor for StringVisitor {
|
||||
{
|
||||
match String::from_utf8(v) {
|
||||
Ok(s) => Ok(s),
|
||||
Err(_) => Err(Error::invalid_type(Type::String)),
|
||||
Err(_) => Err(Error::invalid_value(Unexpected::Bytes, &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,6 +329,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 +373,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 +426,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 +544,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 +579,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 +590,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 +666,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 +678,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 +748,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 +814,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 +827,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 +840,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 +855,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 +868,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 +881,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 +895,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 +908,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 +1010,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 +1030,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 +1042,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 +1057,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))
|
||||
@ -1083,7 +1124,7 @@ impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable +
|
||||
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 +1153,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 +1169,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 +1179,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, &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1166,6 +1199,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 +1235,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)
|
||||
|
@ -8,7 +8,7 @@ use error;
|
||||
#[cfg(all(not(feature = "std"), feature = "collections"))]
|
||||
use collections::{String, Vec};
|
||||
|
||||
use core::fmt;
|
||||
use core::fmt::{self, Display};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -19,206 +19,338 @@ mod from_primitive;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// `Error` is a trait that allows a `Deserialize` to generically create a
|
||||
/// `Deserializer` error.
|
||||
/// The `Error` trait allows `Deserialize` implementations to create descriptive
|
||||
/// error messages belonging to the `Deserializer` against which they are
|
||||
/// currently running.
|
||||
///
|
||||
/// Every `Deserializer` declares an `Error` type that encompasses both
|
||||
/// general-purpose deserialization errors as well as errors specific to the
|
||||
/// particular deserialization format. For example the `Error` type of
|
||||
/// `serde_json` can represent errors like an invalid JSON escape sequence or an
|
||||
/// unterminated string literal, in addition to the error cases that are part of
|
||||
/// this trait.
|
||||
///
|
||||
/// Most deserializers should only need to provide the `Error::custom` method
|
||||
/// and inherit the default behavior for the other methods.
|
||||
pub trait Error: Sized + error::Error {
|
||||
/// Raised when there is general error when deserializing a type.
|
||||
#[cfg(any(feature = "std", feature = "collections"))]
|
||||
fn custom<T: Into<String>>(msg: T) -> Self;
|
||||
fn custom<T: Display>(msg: T) -> Self;
|
||||
|
||||
/// Raised when there is general error when deserializing a type.
|
||||
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
|
||||
fn custom<T: Into<&'static str>>(msg: T) -> Self;
|
||||
|
||||
/// Raised when a `Deserialize` type unexpectedly hit the end of the stream.
|
||||
fn end_of_stream() -> Self;
|
||||
|
||||
/// Raised when a `Deserialize` was passed an incorrect type.
|
||||
fn invalid_type(ty: Type) -> Self {
|
||||
Error::custom(format!("Invalid type. Expected `{:?}`", ty))
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` was passed an incorrect value.
|
||||
fn invalid_value(msg: &str) -> Self {
|
||||
Error::custom(format!("Invalid value: {}", msg))
|
||||
}
|
||||
|
||||
/// Raised when a fixed sized sequence or map was passed in the wrong amount of arguments.
|
||||
/// Raised when a `Deserialize` receives a type different from what it was
|
||||
/// expecting.
|
||||
///
|
||||
/// The parameter `len` is the number of arguments found in the serialization. The sequence
|
||||
/// may either expect more arguments or less arguments.
|
||||
fn invalid_length(len: usize) -> Self {
|
||||
Error::custom(format!("Invalid length: {}", len))
|
||||
/// The `unexp` argument provides information about what type was received.
|
||||
/// This is the type that was present in the input file or other source data
|
||||
/// of the Deserializer.
|
||||
///
|
||||
/// The `exp` argument provides information about what type was being
|
||||
/// expected. This is the type that is written in the program.
|
||||
///
|
||||
/// For example if we try to deserialize a String out of a JSON file
|
||||
/// containing an integer, the unexpected type is the integer and the
|
||||
/// expected type is the string.
|
||||
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
|
||||
struct InvalidType<'a> {
|
||||
unexp: Unexpected<'a>,
|
||||
exp: &'a Expected,
|
||||
}
|
||||
impl<'a> Display for InvalidType<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "invalid type: {}, expected {}", self.unexp, self.exp)
|
||||
}
|
||||
}
|
||||
Error::custom(InvalidType { unexp: unexp, exp: exp })
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` enum type received an unexpected variant.
|
||||
fn unknown_variant(field: &str) -> Self {
|
||||
Error::custom(format!("Unknown variant `{}`", field))
|
||||
/// Raised when a `Deserialize` receives a value of the right type but that
|
||||
/// is wrong for some other reason.
|
||||
///
|
||||
/// The `unexp` argument provides information about what value was received.
|
||||
/// This is the value that was present in the input file or other source
|
||||
/// data of the Deserializer.
|
||||
///
|
||||
/// The `exp` argument provides information about what value was being
|
||||
/// expected. This is the type that is written in the program.
|
||||
///
|
||||
/// For example if we try to deserialize a String out of some binary data
|
||||
/// that is not valid UTF-8, the unexpected value is the bytes and the
|
||||
/// expected value is a string.
|
||||
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
|
||||
struct InvalidValue<'a> {
|
||||
unexp: Unexpected<'a>,
|
||||
exp: &'a Expected,
|
||||
}
|
||||
impl<'a> Display for InvalidValue<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "invalid value: {}, expected {}", self.unexp, self.exp)
|
||||
}
|
||||
}
|
||||
Error::custom(InvalidValue { unexp: unexp, exp: exp })
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` struct type received an unexpected struct field.
|
||||
fn unknown_field(field: &str) -> Self {
|
||||
Error::custom(format!("Unknown field `{}`", field))
|
||||
/// Raised when deserializing a sequence or map and the input data contains
|
||||
/// too many or too few elements.
|
||||
///
|
||||
/// The `len` argument is the number of elements encountered. The sequence
|
||||
/// or map may have expected more arguments or fewer arguments.
|
||||
///
|
||||
/// The `exp` argument provides information about what data was being
|
||||
/// expected. For example `exp` might say that a tuple of size 6 was
|
||||
/// expected.
|
||||
fn invalid_length(len: usize, exp: &Expected) -> Self {
|
||||
struct InvalidLength<'a> {
|
||||
len: usize,
|
||||
exp: &'a Expected,
|
||||
}
|
||||
impl<'a> Display for InvalidLength<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "invalid length {}, expected {}", self.len, self.exp)
|
||||
}
|
||||
}
|
||||
Error::custom(InvalidLength { len: len, exp: exp })
|
||||
}
|
||||
|
||||
/// raised when a `deserialize` struct type did not receive a field.
|
||||
/// Raised when a `Deserialize` enum type received a variant with an
|
||||
/// unrecognized name.
|
||||
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
|
||||
struct UnknownVariant<'a> {
|
||||
variant: &'a str,
|
||||
expected: &'static [&'static str],
|
||||
}
|
||||
impl<'a> Display for UnknownVariant<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.expected.is_empty() {
|
||||
write!(formatter,
|
||||
"unknown variant `{}`, there are no variants",
|
||||
self.variant)
|
||||
} else {
|
||||
write!(formatter,
|
||||
"unknown variant `{}`, expected {}",
|
||||
self.variant,
|
||||
OneOf { names: self.expected })
|
||||
}
|
||||
}
|
||||
}
|
||||
Error::custom(UnknownVariant { variant: variant, expected: expected })
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` struct type received a field with an
|
||||
/// unrecognized name.
|
||||
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
|
||||
struct UnknownField<'a> {
|
||||
field: &'a str,
|
||||
expected: &'static [&'static str],
|
||||
}
|
||||
impl<'a> Display for UnknownField<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.expected.is_empty() {
|
||||
write!(formatter,
|
||||
"unknown field `{}`, there are no fields",
|
||||
self.field)
|
||||
} else {
|
||||
write!(formatter,
|
||||
"unknown field `{}`, expected {}",
|
||||
self.field,
|
||||
OneOf { names: self.expected })
|
||||
}
|
||||
}
|
||||
}
|
||||
Error::custom(UnknownField { field: field, expected: expected })
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` struct type expected to receive a required
|
||||
/// field with a particular name but that field was not present in the
|
||||
/// input.
|
||||
fn missing_field(field: &'static str) -> Self {
|
||||
Error::custom(format!("Missing field `{}`", field))
|
||||
struct MissingField {
|
||||
field: &'static str,
|
||||
}
|
||||
impl Display for MissingField {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "missing field `{}`", self.field)
|
||||
}
|
||||
}
|
||||
Error::custom(MissingField { field: field })
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` struct type received more than one of the
|
||||
/// same struct field.
|
||||
/// same field.
|
||||
fn duplicate_field(field: &'static str) -> Self {
|
||||
Error::custom(format!("Duplicate field `{}`", field))
|
||||
struct DuplicateField {
|
||||
field: &'static str,
|
||||
}
|
||||
impl Display for DuplicateField {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "duplicate field `{}`", self.field)
|
||||
}
|
||||
}
|
||||
Error::custom(DuplicateField { field: field })
|
||||
}
|
||||
}
|
||||
|
||||
/// `Type` represents all the primitive types that can be deserialized. This is used by
|
||||
/// `Error::invalid_type`.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Type {
|
||||
/// Represents a `bool` type.
|
||||
Bool,
|
||||
/// `Unexpected` represents an unexpected invocation of any one of the `Visitor`
|
||||
/// trait methods.
|
||||
///
|
||||
/// This is used as an argument to the `invalid_type`, `invalid_value`, and
|
||||
/// `invalid_length` methods of the `Error` trait to build error messages.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use serde::de::{Error, Unexpected, Visitor};
|
||||
/// # use std::fmt;
|
||||
/// # struct Example;
|
||||
/// # impl Visitor for Example {
|
||||
/// # type Value = ();
|
||||
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||
/// where E: Error
|
||||
/// {
|
||||
/// Err(Error::invalid_type(Unexpected::Bool(v), &self))
|
||||
/// }
|
||||
/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # write!(formatter, "definitely not a boolean")
|
||||
/// # }
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum Unexpected<'a> {
|
||||
/// The input contained a boolean value that was not expected.
|
||||
Bool(bool),
|
||||
|
||||
/// Represents a `usize` type.
|
||||
Usize,
|
||||
/// The input contained an unsigned integer `usize`, `u8`, `u16`, `u32` or
|
||||
/// `u64` that was not expected.
|
||||
Unsigned(u64),
|
||||
|
||||
/// Represents a `u8` type.
|
||||
U8,
|
||||
/// The input contained a signed integer `isize`, `i8`, `i16`, `i32` or
|
||||
/// `i64` that was not expected.
|
||||
Signed(i64),
|
||||
|
||||
/// Represents a `u16` type.
|
||||
U16,
|
||||
/// The input contained a floating point `f32` or `f64` that was not
|
||||
/// expected.
|
||||
Float(f64),
|
||||
|
||||
/// Represents a `u32` type.
|
||||
U32,
|
||||
/// The input contained a `char` that was not expected.
|
||||
Char(char),
|
||||
|
||||
/// Represents a `u64` type.
|
||||
U64,
|
||||
/// The input contained a `&str` or `String` that was not expected.
|
||||
Str(&'a str),
|
||||
|
||||
/// Represents a `isize` type.
|
||||
Isize,
|
||||
|
||||
/// Represents a `i8` type.
|
||||
I8,
|
||||
|
||||
/// Represents a `i16` type.
|
||||
I16,
|
||||
|
||||
/// Represents a `i32` type.
|
||||
I32,
|
||||
|
||||
/// Represents a `i64` type.
|
||||
I64,
|
||||
|
||||
/// Represents a `f32` type.
|
||||
F32,
|
||||
|
||||
/// Represents a `f64` type.
|
||||
F64,
|
||||
|
||||
/// Represents a `char` type.
|
||||
Char,
|
||||
|
||||
/// Represents a `&str` type.
|
||||
Str,
|
||||
|
||||
/// Represents a `String` type.
|
||||
String,
|
||||
|
||||
/// Represents a `()` type.
|
||||
/// The input contained a unit `()` that was not expected.
|
||||
Unit,
|
||||
|
||||
/// Represents an `Option<T>` type.
|
||||
/// The input contained an `Option<T>` that was not expected.
|
||||
Option,
|
||||
|
||||
/// Represents a sequence type.
|
||||
Seq,
|
||||
|
||||
/// Represents a map type.
|
||||
Map,
|
||||
|
||||
/// Represents a unit struct type.
|
||||
UnitStruct,
|
||||
|
||||
/// Represents a newtype type.
|
||||
/// The input contained a newtype struct that was not expected.
|
||||
NewtypeStruct,
|
||||
|
||||
/// Represents a tuple struct type.
|
||||
TupleStruct,
|
||||
/// The input contained a sequence that was not expected.
|
||||
Seq,
|
||||
|
||||
/// Represents a struct type.
|
||||
Struct,
|
||||
/// The input contained a map that was not expected.
|
||||
Map,
|
||||
|
||||
/// Represents a struct field name.
|
||||
FieldName,
|
||||
|
||||
/// Represents a tuple type.
|
||||
Tuple,
|
||||
|
||||
/// Represents an `enum` type.
|
||||
/// The input contained an enum that was not expected.
|
||||
Enum,
|
||||
|
||||
/// Represents an enum variant name.
|
||||
VariantName,
|
||||
|
||||
/// Represents a struct variant.
|
||||
StructVariant,
|
||||
|
||||
/// Represents a tuple variant.
|
||||
TupleVariant,
|
||||
|
||||
/// Represents a unit variant.
|
||||
/// The input contained a unit variant that was not expected.
|
||||
UnitVariant,
|
||||
|
||||
/// Represents a newtype variant.
|
||||
/// The input contained a newtype variant that was not expected.
|
||||
NewtypeVariant,
|
||||
|
||||
/// Represents a `&[u8]` type.
|
||||
Bytes,
|
||||
/// The input contained a tuple variant that was not expected.
|
||||
TupleVariant,
|
||||
|
||||
/// Represents a `Vec<u8>` type.
|
||||
ByteBuf,
|
||||
/// The input contained a struct variant that was not expected.
|
||||
StructVariant,
|
||||
|
||||
/// The input contained a `&[u8]` or `Vec<u8>` that was not expected.
|
||||
Bytes,
|
||||
}
|
||||
|
||||
impl fmt::Display for Type {
|
||||
impl<'a> fmt::Display for Unexpected<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
let display = match *self {
|
||||
Type::Bool => "bool",
|
||||
Type::Usize => "usize",
|
||||
Type::U8 => "u8",
|
||||
Type::U16 => "u16",
|
||||
Type::U32 => "u32",
|
||||
Type::U64 => "u64",
|
||||
Type::Isize => "isize",
|
||||
Type::I8 => "i8",
|
||||
Type::I16 => "i16",
|
||||
Type::I32 => "i32",
|
||||
Type::I64 => "i64",
|
||||
Type::F32 => "f32",
|
||||
Type::F64 => "f64",
|
||||
Type::Char => "char",
|
||||
Type::Str => "str",
|
||||
Type::String => "string",
|
||||
Type::Unit => "unit",
|
||||
Type::Option => "option",
|
||||
Type::Seq => "seq",
|
||||
Type::Map => "map",
|
||||
Type::UnitStruct => "unit struct",
|
||||
Type::NewtypeStruct => "newtype struct",
|
||||
Type::TupleStruct => "tuple struct",
|
||||
Type::Struct => "struct",
|
||||
Type::FieldName => "field name",
|
||||
Type::Tuple => "tuple",
|
||||
Type::Enum => "enum",
|
||||
Type::VariantName => "variant name",
|
||||
Type::StructVariant => "struct variant",
|
||||
Type::TupleVariant => "tuple variant",
|
||||
Type::UnitVariant => "unit variant",
|
||||
Type::NewtypeVariant => "newtype variant",
|
||||
Type::Bytes => "bytes",
|
||||
Type::ByteBuf => "bytes buf",
|
||||
};
|
||||
display.fmt(formatter)
|
||||
use self::Unexpected::*;
|
||||
match *self {
|
||||
Bool(b) => write!(formatter, "boolean `{}`", b),
|
||||
Unsigned(i) => write!(formatter, "integer `{}`", i),
|
||||
Signed(i) => write!(formatter, "integer `{}`", i),
|
||||
Float(f) => write!(formatter, "floating point `{}`", f),
|
||||
Char(c) => write!(formatter, "character `{}`", c),
|
||||
Str(s) => write!(formatter, "string {:?}", s),
|
||||
Unit => write!(formatter, "unit value"),
|
||||
Option => write!(formatter, "Option value"),
|
||||
NewtypeStruct => write!(formatter, "newtype struct"),
|
||||
Seq => write!(formatter, "sequence"),
|
||||
Map => write!(formatter, "map"),
|
||||
Enum => write!(formatter, "enum"),
|
||||
UnitVariant => write!(formatter, "unit variant"),
|
||||
NewtypeVariant => write!(formatter, "newtype variant"),
|
||||
TupleVariant => write!(formatter, "tuple variant"),
|
||||
StructVariant => write!(formatter, "struct variant"),
|
||||
Bytes => write!(formatter, "byte array"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `Expected` represents an explanation of what data a `Visitor` was expecting
|
||||
/// to receive.
|
||||
///
|
||||
/// This is used as an argument to the `invalid_type`, `invalid_value`, and
|
||||
/// `invalid_length` methods of the `Error` trait to build error messages. The
|
||||
/// message should complete the sentence "This Visitor expects to receive ...",
|
||||
/// for example the message could be "an integer between 0 and 64". The message
|
||||
/// should not be capitalized and should not end with a period.
|
||||
///
|
||||
/// Within the context of a `Visitor` implementation, the `Visitor` itself
|
||||
/// (`&self`) is an implementation of this trait.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use serde::de::{Error, Unexpected, Visitor};
|
||||
/// # use std::fmt;
|
||||
/// # struct Example;
|
||||
/// # impl Visitor for Example {
|
||||
/// # type Value = ();
|
||||
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||
/// where E: Error
|
||||
/// {
|
||||
/// Err(Error::invalid_type(Unexpected::Bool(v), &self))
|
||||
/// }
|
||||
/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # write!(formatter, "definitely not a boolean")
|
||||
/// # }
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Outside of a `Visitor`, `&"..."` can be used.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use serde::de::{Error, Unexpected};
|
||||
/// # fn example<E: Error>() -> Result<(), E> {
|
||||
/// # let v = true;
|
||||
/// return Err(Error::invalid_type(Unexpected::Bool(v), &"a negative integer"));
|
||||
/// # }
|
||||
/// ```
|
||||
pub trait Expected {
|
||||
/// Format an explanation of what data was being expected. Same signature as
|
||||
/// the `Display` and `Debug` traits.
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
|
||||
}
|
||||
|
||||
impl<T> Expected for T where T: Visitor {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.expecting(formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Expected for &'a str {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Display for Expected + 'a {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
Expected::fmt(self, formatter)
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,6 +408,7 @@ pub trait Deserialize: Sized {
|
||||
///
|
||||
/// ```rust
|
||||
/// # use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor};
|
||||
/// # use std::fmt;
|
||||
/// # use std::marker::PhantomData;
|
||||
/// #
|
||||
/// // A DeserializeSeed implementation that uses stateful deserialization to
|
||||
@ -315,6 +448,10 @@ pub trait Deserialize: Sized {
|
||||
/// }
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// #
|
||||
/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # write!(formatter, "an array of integers")
|
||||
/// # }
|
||||
/// }
|
||||
///
|
||||
/// deserializer.deserialize_seq(ExtendVecVisitor(self.0))
|
||||
@ -345,6 +482,10 @@ pub trait Deserialize: Sized {
|
||||
/// // Return the finished vec.
|
||||
/// Ok(vec)
|
||||
/// }
|
||||
/// #
|
||||
/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # write!(formatter, "an array of arrays")
|
||||
/// # }
|
||||
/// }
|
||||
///
|
||||
/// # fn example<D: Deserializer>(deserializer: D) -> Result<(), D::Error> {
|
||||
@ -570,16 +711,62 @@ pub trait Deserializer: Sized {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// This trait represents a visitor that walks through a deserializer.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use serde::de::{Error, Unexpected, Visitor};
|
||||
/// # use std::fmt;
|
||||
/// /// A visitor that deserializes a long string - a string containing at least
|
||||
/// /// some minimum number of bytes.
|
||||
/// struct LongString {
|
||||
/// min: usize,
|
||||
/// }
|
||||
///
|
||||
/// impl Visitor for LongString {
|
||||
/// type Value = String;
|
||||
///
|
||||
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// write!(formatter, "a string containing at least {} bytes", self.min)
|
||||
/// }
|
||||
///
|
||||
/// fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||
/// where E: Error
|
||||
/// {
|
||||
/// if s.len() >= self.min {
|
||||
/// Ok(s.to_owned())
|
||||
/// } else {
|
||||
/// Err(Error::invalid_value(Unexpected::Str(s), &self))
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub trait Visitor: Sized {
|
||||
/// The value produced by this visitor.
|
||||
type Value;
|
||||
|
||||
/// Format a message stating what data this Visitor expects to receive.
|
||||
///
|
||||
/// This is used in error messages. The message should complete the sentence
|
||||
/// "This Visitor expects to receive ...", for example the message could be
|
||||
/// "an integer between 0 and 64". The message should not be capitalized and
|
||||
/// should not end with a period.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::fmt;
|
||||
/// # struct S { max: usize }
|
||||
/// # impl serde::de::Visitor for S {
|
||||
/// # type Value = ();
|
||||
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// write!(formatter, "an integer between 0 and {}", self.max)
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
|
||||
|
||||
/// `visit_bool` deserializes a `bool` into a `Value`.
|
||||
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
let _ = v;
|
||||
Err(Error::invalid_type(Type::Bool))
|
||||
Err(Error::invalid_type(Unexpected::Bool(v), &self))
|
||||
}
|
||||
|
||||
/// `visit_isize` deserializes a `isize` into a `Value`.
|
||||
@ -614,8 +801,7 @@ pub trait Visitor: Sized {
|
||||
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
let _ = v;
|
||||
Err(Error::invalid_type(Type::I64))
|
||||
Err(Error::invalid_type(Unexpected::Signed(v), &self))
|
||||
}
|
||||
|
||||
/// `visit_usize` deserializes a `usize` into a `Value`.
|
||||
@ -650,8 +836,7 @@ pub trait Visitor: Sized {
|
||||
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
let _ = v;
|
||||
Err(Error::invalid_type(Type::U64))
|
||||
Err(Error::invalid_type(Unexpected::Unsigned(v), &self))
|
||||
}
|
||||
|
||||
/// `visit_f32` deserializes a `f32` into a `Value`.
|
||||
@ -665,8 +850,7 @@ pub trait Visitor: Sized {
|
||||
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
let _ = v;
|
||||
Err(Error::invalid_type(Type::F64))
|
||||
Err(Error::invalid_type(Unexpected::Float(v), &self))
|
||||
}
|
||||
|
||||
/// `visit_char` deserializes a `char` into a `Value`.
|
||||
@ -681,8 +865,7 @@ pub trait Visitor: Sized {
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
let _ = v;
|
||||
Err(Error::invalid_type(Type::Str))
|
||||
Err(Error::invalid_type(Unexpected::Str(v), &self))
|
||||
}
|
||||
|
||||
/// `visit_string` deserializes a `String` into a `Value`. This allows a deserializer to avoid
|
||||
@ -700,23 +883,14 @@ pub trait Visitor: Sized {
|
||||
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::invalid_type(Type::Unit))
|
||||
}
|
||||
|
||||
/// `visit_unit_struct` deserializes a unit struct into a `Value`.
|
||||
#[inline]
|
||||
fn visit_unit_struct<E>(self, name: &'static str) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
let _ = name;
|
||||
self.visit_unit()
|
||||
Err(Error::invalid_type(Unexpected::Unit, &self))
|
||||
}
|
||||
|
||||
/// `visit_none` deserializes a none value into a `Value`.
|
||||
fn visit_none<E>(self) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::invalid_type(Type::Option))
|
||||
Err(Error::invalid_type(Unexpected::Option, &self))
|
||||
}
|
||||
|
||||
/// `visit_some` deserializes a value into a `Value`.
|
||||
@ -724,7 +898,7 @@ pub trait Visitor: Sized {
|
||||
where D: Deserializer,
|
||||
{
|
||||
let _ = deserializer;
|
||||
Err(Error::invalid_type(Type::Option))
|
||||
Err(Error::invalid_type(Unexpected::Option, &self))
|
||||
}
|
||||
|
||||
/// `visit_newtype_struct` deserializes a value into a `Value`.
|
||||
@ -732,7 +906,7 @@ pub trait Visitor: Sized {
|
||||
where D: Deserializer,
|
||||
{
|
||||
let _ = deserializer;
|
||||
Err(Error::invalid_type(Type::NewtypeStruct))
|
||||
Err(Error::invalid_type(Unexpected::NewtypeStruct, &self))
|
||||
}
|
||||
|
||||
/// `visit_seq` deserializes a `SeqVisitor` into a `Value`.
|
||||
@ -740,7 +914,7 @@ pub trait Visitor: Sized {
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
let _ = visitor;
|
||||
Err(Error::invalid_type(Type::Seq))
|
||||
Err(Error::invalid_type(Unexpected::Seq, &self))
|
||||
}
|
||||
|
||||
/// `visit_map` deserializes a `MapVisitor` into a `Value`.
|
||||
@ -748,7 +922,7 @@ pub trait Visitor: Sized {
|
||||
where V: MapVisitor,
|
||||
{
|
||||
let _ = visitor;
|
||||
Err(Error::invalid_type(Type::Map))
|
||||
Err(Error::invalid_type(Unexpected::Map, &self))
|
||||
}
|
||||
|
||||
/// `visit_enum` deserializes a `EnumVisitor` into a `Value`.
|
||||
@ -756,7 +930,7 @@ pub trait Visitor: Sized {
|
||||
where V: EnumVisitor,
|
||||
{
|
||||
let _ = visitor;
|
||||
Err(Error::invalid_type(Type::Enum))
|
||||
Err(Error::invalid_type(Unexpected::Enum, &self))
|
||||
}
|
||||
|
||||
/// `visit_bytes` deserializes a `&[u8]` into a `Value`.
|
||||
@ -764,7 +938,7 @@ pub trait Visitor: Sized {
|
||||
where E: Error,
|
||||
{
|
||||
let _ = v;
|
||||
Err(Error::invalid_type(Type::Bytes))
|
||||
Err(Error::invalid_type(Unexpected::Bytes, &self))
|
||||
}
|
||||
|
||||
/// `visit_byte_buf` deserializes a `Vec<u8>` into a `Value`.
|
||||
@ -1100,3 +1274,34 @@ pub trait VariantVisitor: Sized {
|
||||
visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Used in error messages.
|
||||
///
|
||||
/// - expected `a`
|
||||
/// - expected `a` or `b`
|
||||
/// - expected one of `a`, `b`, `c`
|
||||
struct OneOf {
|
||||
names: &'static [&'static str],
|
||||
}
|
||||
|
||||
impl Display for OneOf {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.names.len() {
|
||||
0 => panic!(), // special case elsewhere
|
||||
1 => write!(formatter, "`{}`", self.names[0]),
|
||||
2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]),
|
||||
_ => {
|
||||
try!(write!(formatter, "one of "));
|
||||
for (i, alt) in self.names.iter().enumerate() {
|
||||
if i > 0 {
|
||||
try!(write!(formatter, ", "));
|
||||
}
|
||||
try!(write!(formatter, "`{}`", alt));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ use std::error;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use error;
|
||||
|
||||
use core::fmt;
|
||||
use core::fmt::{self, Display};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use de::{self, SeqVisitor};
|
||||
@ -48,102 +48,46 @@ 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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,7 +406,7 @@ impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
|
||||
if self.len == 0 {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err(de::Error::invalid_length(self.len))
|
||||
Err(de::Error::invalid_length(self.len, &"TODO"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,7 +573,7 @@ impl<I, K, V, E> MapDeserializer<I, K, V, E>
|
||||
|
||||
fn end(&mut self) -> Result<(), E> {
|
||||
match self.len {
|
||||
Some(len) if len > 0 => Err(de::Error::invalid_length(len)),
|
||||
Some(len) if len > 0 => Err(de::Error::invalid_length(len, &"TODO")),
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
@ -663,7 +607,7 @@ impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
|
||||
where V_: de::Visitor,
|
||||
{
|
||||
match self.len {
|
||||
Some(map_len) if map_len != len => Err(de::Error::invalid_length(len)),
|
||||
Some(map_len) if map_len != len => Err(de::Error::invalid_length(len, &"TODO")),
|
||||
_ => {
|
||||
let value = try!(visitor.visit_seq(&mut self));
|
||||
try!(self.end());
|
||||
@ -702,14 +646,11 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
|
||||
fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where T: de::DeserializeSeed,
|
||||
{
|
||||
match self.value.take() {
|
||||
Some(value) => {
|
||||
seed.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_seed<TK, TV>(&mut self, kseed: TK, vseed: TV) -> Result<Option<(TK::Value, TV::Value)>, Self::Error>
|
||||
@ -789,7 +730,7 @@ 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))
|
||||
Err(de::Error::invalid_length(pair_visitor.size_hint().0, &"TODO"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,7 +740,7 @@ 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))
|
||||
Err(de::Error::invalid_length(len, &"TODO"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -977,7 +918,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>);
|
||||
@ -998,7 +939,7 @@ mod private {
|
||||
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 +947,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 +955,7 @@ 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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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,6 +516,8 @@ fn deserialize_item_enum(
|
||||
|
||||
let type_name = item_attrs.name().deserialize_name();
|
||||
|
||||
let expecting = format!("enum {}", type_ident);
|
||||
|
||||
let variant_names_idents = variants.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||
@ -555,6 +584,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,
|
||||
{
|
||||
@ -659,11 +692,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! {
|
||||
@ -688,6 +721,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")
|
||||
}
|
||||
|
||||
fn visit_str<__E>(self, value: &str) -> ::std::result::Result<__Field, __E>
|
||||
where __E: _serde::de::Error
|
||||
{
|
||||
|
@ -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!(),
|
||||
|
@ -43,7 +43,7 @@ impl<I> Deserializer<I>
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,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)
|
||||
}
|
||||
@ -273,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,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); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -511,7 +511,7 @@ impl<'a, I> SeqVisitor for DeserializerSeqVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,7 +547,7 @@ impl<'a, I> SeqVisitor for DeserializerArrayVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@ impl<'a, I> SeqVisitor for DeserializerTupleVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -617,7 +617,7 @@ impl<'a, I> SeqVisitor for DeserializerTupleStructVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -652,7 +652,7 @@ impl<'a, I> SeqVisitor for DeserializerVariantSeqVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -688,7 +688,7 @@ impl<'a, I> MapVisitor for DeserializerMapVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -730,7 +730,7 @@ impl<'a, I> MapVisitor for DeserializerStructVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,7 +773,7 @@ impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I>
|
||||
let value = try!(seed.deserialize(&mut *self.de));
|
||||
Ok((value, self))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -792,7 +792,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
|
||||
Some(_) => {
|
||||
Deserialize::deserialize(self.de)
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -807,7 +807,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
|
||||
Some(_) => {
|
||||
seed.deserialize(self.de)
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
@ -838,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),
|
||||
}
|
||||
}
|
||||
|
||||
@ -869,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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -900,7 +900,7 @@ impl<'a, I> MapVisitor for DeserializerVariantMapVisitor<'a, I>
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStream),
|
||||
None => Err(Error::EndOfTokens),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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, Type};
|
||||
use serde::Deserialize;
|
||||
|
||||
extern crate fnv;
|
||||
use self::fnv::FnvHasher;
|
||||
@ -849,7 +849,7 @@ declare_error_tests! {
|
||||
Token::StructSep,
|
||||
Token::Str("d"),
|
||||
],
|
||||
Error::UnknownField("d".to_owned()),
|
||||
Error::Message("unknown field `d`, expected `a` or `b`".to_owned()),
|
||||
}
|
||||
test_skipped_field_is_unknown<StructDenyUnknown> {
|
||||
&[
|
||||
@ -857,7 +857,7 @@ declare_error_tests! {
|
||||
Token::StructSep,
|
||||
Token::Str("b"),
|
||||
],
|
||||
Error::UnknownField("b".to_owned()),
|
||||
Error::Message("unknown field `b`, expected `a` or `b`".to_owned()),
|
||||
}
|
||||
test_skip_all_deny_unknown<StructSkipAllDenyUnknown> {
|
||||
&[
|
||||
@ -865,25 +865,25 @@ declare_error_tests! {
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
],
|
||||
Error::UnknownField("a".to_owned()),
|
||||
Error::Message("unknown field `a`, expected `a`".to_owned()),
|
||||
}
|
||||
test_unknown_variant<Enum> {
|
||||
&[
|
||||
Token::EnumUnit("Enum", "Foo"),
|
||||
],
|
||||
Error::UnknownVariant("Foo".to_owned()),
|
||||
Error::Message("unknown variant `Foo`, expected one of `Skipped`, `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 `Skipped`, `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`, expected `Skipped`".to_owned()),
|
||||
}
|
||||
test_struct_seq_too_long<Struct> {
|
||||
&[
|
||||
@ -904,7 +904,7 @@ declare_error_tests! {
|
||||
Token::MapSep,
|
||||
Token::Str("a"),
|
||||
],
|
||||
Error::DuplicateField("a"),
|
||||
Error::Message("duplicate field `a`".to_owned()),
|
||||
}
|
||||
test_duplicate_field_enum<Enum> {
|
||||
&[
|
||||
@ -916,7 +916,7 @@ declare_error_tests! {
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
],
|
||||
Error::DuplicateField("a"),
|
||||
Error::Message("duplicate field `a`".to_owned()),
|
||||
}
|
||||
test_enum_unit_usize<Enum> {
|
||||
&[
|
||||
@ -924,7 +924,7 @@ declare_error_tests! {
|
||||
Token::Usize(0),
|
||||
Token::Unit,
|
||||
],
|
||||
Error::InvalidType(Type::U64),
|
||||
Error::Message("invalid type: integer `0`, expected field name".into()),
|
||||
}
|
||||
test_enum_unit_bytes<Enum> {
|
||||
&[
|
||||
@ -932,6 +932,6 @@ declare_error_tests! {
|
||||
Token::Bytes(b"Unit"),
|
||||
Token::Unit,
|
||||
],
|
||||
Error::InvalidType(Type::Bytes),
|
||||
Error::Message("invalid type: byte array, expected field name".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…
Reference in New Issue
Block a user