Skip to content

Commit

Permalink
Merge pull request #847 from serde-rs/error
Browse files Browse the repository at this point in the history
Remove serde::error::Error
  • Loading branch information
dtolnay authored Apr 5, 2017
2 parents 1e32329 + 11c8969 commit 2fe67d3
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 173 deletions.
242 changes: 125 additions & 117 deletions serde/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@
#[cfg(feature = "std")]
use std::error;
#[cfg(not(feature = "std"))]
use error;

#[cfg(all(not(feature = "std"), feature = "collections"))]
use collections::{String, Vec};
Expand All @@ -123,130 +121,140 @@ pub use self::ignored_any::IgnoredAny;

///////////////////////////////////////////////////////////////////////////////

/// 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.
///
/// The message should not be capitalized and should not end with a period.
///
/// ```rust
/// # use serde::de::{Deserialize, Deserializer, Error};
/// # use std::str::FromStr;
/// # #[allow(dead_code)]
/// # struct IpAddr;
/// # impl FromStr for IpAddr {
/// # type Err = String;
/// # fn from_str(_: &str) -> Result<Self, String> { unimplemented!() }
/// # }
/// impl<'de> Deserialize<'de> for IpAddr {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where D: Deserializer<'de>
/// {
/// let s = try!(String::deserialize(deserializer));
/// s.parse().map_err(Error::custom)
/// }
/// }
/// ```
fn custom<T: Display>(msg: T) -> Self;
macro_rules! declare_error_trait {
(Error: Sized $(+ $($supertrait:ident)::*)*) => {
/// 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 $(+ $($supertrait)::*)* {
/// Raised when there is general error when deserializing a type.
///
/// The message should not be capitalized and should not end with a period.
///
/// ```rust
/// # use serde::de::{Deserialize, Deserializer, Error};
/// # use std::str::FromStr;
/// # #[allow(dead_code)]
/// # struct IpAddr;
/// # impl FromStr for IpAddr {
/// # type Err = String;
/// # fn from_str(_: &str) -> Result<Self, String> { unimplemented!() }
/// # }
/// impl<'de> Deserialize<'de> for IpAddr {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where D: Deserializer<'de>
/// {
/// let s = try!(String::deserialize(deserializer));
/// s.parse().map_err(Error::custom)
/// }
/// }
/// ```
fn custom<T: Display>(msg: T) -> Self;

/// Raised when a `Deserialize` receives a type different from what it was
/// expecting.
///
/// 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 {
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
}

/// Raised when a `Deserialize` receives a type different from what it was
/// expecting.
///
/// 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 {
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
}
/// 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 {
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
}

/// 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 {
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
}
/// 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 {
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
}

/// 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 {
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
}
/// Raised when a `Deserialize` enum type received a variant with an
/// unrecognized name.
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown variant `{}`, there are no variants",
variant))
} else {
Error::custom(format_args!("unknown variant `{}`, expected {}",
variant,
OneOf { names: expected }))
}
}

/// Raised when a `Deserialize` enum type received a variant with an
/// unrecognized name.
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown variant `{}`, there are no variants",
variant))
} else {
Error::custom(format_args!("unknown variant `{}`, expected {}",
variant,
OneOf { names: expected }))
}
}
/// Raised when a `Deserialize` struct type received a field with an
/// unrecognized name.
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown field `{}`, there are no fields",
field))
} else {
Error::custom(format_args!("unknown field `{}`, expected {}",
field,
OneOf { names: 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_args!("missing field `{}`", field))
}

/// Raised when a `Deserialize` struct type received a field with an
/// unrecognized name.
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown field `{}`, there are no fields",
field))
} else {
Error::custom(format_args!("unknown field `{}`, expected {}",
field,
OneOf { names: expected }))
/// Raised when a `Deserialize` struct type received more than one of the
/// same field.
fn duplicate_field(field: &'static str) -> Self {
Error::custom(format_args!("duplicate field `{}`", field))
}
}
}
}

/// 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_args!("missing field `{}`", field))
}
#[cfg(feature = "std")]
declare_error_trait!(Error: Sized + error::Error);

/// Raised when a `Deserialize` struct type received more than one of the
/// same field.
fn duplicate_field(field: &'static str) -> Self {
Error::custom(format_args!("duplicate field `{}`", field))
}
}
#[cfg(not(feature = "std"))]
declare_error_trait!(Error: Sized);

/// `Unexpected` represents an unexpected invocation of any one of the `Visitor`
/// trait methods.
Expand Down
9 changes: 1 addition & 8 deletions serde/src/de/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ use collections::string::ToString;
use core::hash::Hash;
#[cfg(feature = "std")]
use std::error;
#[cfg(not(feature = "std"))]
use error;

use core::fmt::{self, Display};
use core::iter::{self, Iterator};
Expand Down Expand Up @@ -67,16 +65,11 @@ impl Display for Error {
}
}

#[cfg(feature = "std")]
impl error::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))]
fn description(&self) -> &str {
&self.err
}

#[cfg(not(any(feature = "std", feature = "collections")))]
fn description(&self) -> &str {
"Serde deserialization error"
}
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
17 changes: 0 additions & 17 deletions serde/src/error.rs

This file was deleted.

2 changes: 0 additions & 2 deletions serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ pub mod de;
#[doc(hidden)]
pub mod iter;
pub mod ser;
#[cfg_attr(feature = "std", doc(hidden))]
pub mod error;
mod utils;

// Generated code uses these to support no_std. Not public API.
Expand Down
Loading

0 comments on commit 2fe67d3

Please sign in to comment.