This commit is contained in:
David Tolnay 2017-01-11 02:39:16 -08:00
parent d1325862f7
commit a4126e4c5a
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
15 changed files with 680 additions and 511 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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(())
}
}
}
}

View File

@ -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"))
}
}
}

View File

@ -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>()
}
}

View File

@ -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;

View File

@ -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")),
}
}
}

View File

@ -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;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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
{

View File

@ -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!(),

View File

@ -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),
}
}

View File

@ -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",
}
}
}

View File

@ -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()),
);
}

View File

@ -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()),
}
}

View File

@ -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()));
}