Merge pull request #847 from serde-rs/error

Remove serde::error::Error
This commit is contained in:
David Tolnay
2017-04-05 16:37:18 -07:00
committed by GitHub
5 changed files with 167 additions and 175 deletions
+127 -119
View File
@@ -96,8 +96,6 @@
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error; use std::error;
#[cfg(not(feature = "std"))]
use error;
#[cfg(all(not(feature = "std"), feature = "collections"))] #[cfg(all(not(feature = "std"), feature = "collections"))]
use collections::{String, Vec}; use collections::{String, Vec};
@@ -123,131 +121,141 @@ pub use self::ignored_any::IgnoredAny;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// The `Error` trait allows `Deserialize` implementations to create descriptive macro_rules! declare_error_trait {
/// error messages belonging to the `Deserializer` against which they are (Error: Sized $(+ $($supertrait:ident)::*)*) => {
/// currently running. /// The `Error` trait allows `Deserialize` implementations to create descriptive
/// /// error messages belonging to the `Deserializer` against which they are
/// Every `Deserializer` declares an `Error` type that encompasses both /// currently running.
/// general-purpose deserialization errors as well as errors specific to the ///
/// particular deserialization format. For example the `Error` type of /// Every `Deserializer` declares an `Error` type that encompasses both
/// `serde_json` can represent errors like an invalid JSON escape sequence or an /// general-purpose deserialization errors as well as errors specific to the
/// unterminated string literal, in addition to the error cases that are part of /// particular deserialization format. For example the `Error` type of
/// this trait. /// `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
/// Most deserializers should only need to provide the `Error::custom` method /// this trait.
/// and inherit the default behavior for the other methods. ///
pub trait Error: Sized + error::Error { /// Most deserializers should only need to provide the `Error::custom` method
/// Raised when there is general error when deserializing a type. /// and inherit the default behavior for the other methods.
/// pub trait Error: Sized $(+ $($supertrait)::*)* {
/// The message should not be capitalized and should not end with a period. /// Raised when there is general error when deserializing a type.
/// ///
/// ```rust /// The message should not be capitalized and should not end with a period.
/// # use serde::de::{Deserialize, Deserializer, Error}; ///
/// # use std::str::FromStr; /// ```rust
/// # #[allow(dead_code)] /// # use serde::de::{Deserialize, Deserializer, Error};
/// # struct IpAddr; /// # use std::str::FromStr;
/// # impl FromStr for IpAddr { /// # #[allow(dead_code)]
/// # type Err = String; /// # struct IpAddr;
/// # fn from_str(_: &str) -> Result<Self, String> { unimplemented!() } /// # impl FromStr for IpAddr {
/// # } /// # type Err = String;
/// impl<'de> Deserialize<'de> for IpAddr { /// # fn from_str(_: &str) -> Result<Self, String> { unimplemented!() }
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> /// # }
/// where D: Deserializer<'de> /// impl<'de> Deserialize<'de> for IpAddr {
/// { /// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// let s = try!(String::deserialize(deserializer)); /// where D: Deserializer<'de>
/// s.parse().map_err(Error::custom) /// {
/// } /// let s = try!(String::deserialize(deserializer));
/// } /// s.parse().map_err(Error::custom)
/// ``` /// }
fn custom<T: Display>(msg: T) -> Self; /// }
/// ```
fn custom<T: Display>(msg: T) -> Self;
/// Raised when a `Deserialize` receives a type different from what it was /// Raised when a `Deserialize` receives a type different from what it was
/// expecting. /// expecting.
/// ///
/// The `unexp` argument provides information about what type was received. /// 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 /// This is the type that was present in the input file or other source data
/// of the Deserializer. /// of the Deserializer.
/// ///
/// The `exp` argument provides information about what type was being /// The `exp` argument provides information about what type was being
/// expected. This is the type that is written in the program. /// 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 /// 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 /// containing an integer, the unexpected type is the integer and the
/// expected type is the string. /// expected type is the string.
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self { fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
} }
/// Raised when a `Deserialize` receives a value of the right type but that /// Raised when a `Deserialize` receives a value of the right type but that
/// is wrong for some other reason. /// is wrong for some other reason.
/// ///
/// The `unexp` argument provides information about what value was received. /// The `unexp` argument provides information about what value was received.
/// This is the value that was present in the input file or other source /// This is the value that was present in the input file or other source
/// data of the Deserializer. /// data of the Deserializer.
/// ///
/// The `exp` argument provides information about what value was being /// The `exp` argument provides information about what value was being
/// expected. This is the type that is written in the program. /// 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 /// 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 /// that is not valid UTF-8, the unexpected value is the bytes and the
/// expected value is a string. /// expected value is a string.
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self { fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp)) Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
} }
/// Raised when deserializing a sequence or map and the input data contains /// Raised when deserializing a sequence or map and the input data contains
/// too many or too few elements. /// too many or too few elements.
/// ///
/// The `len` argument is the number of elements encountered. The sequence /// The `len` argument is the number of elements encountered. The sequence
/// or map may have expected more arguments or fewer arguments. /// or map may have expected more arguments or fewer arguments.
/// ///
/// The `exp` argument provides information about what data was being /// The `exp` argument provides information about what data was being
/// expected. For example `exp` might say that a tuple of size 6 was /// expected. For example `exp` might say that a tuple of size 6 was
/// expected. /// expected.
fn invalid_length(len: usize, exp: &Expected) -> Self { fn invalid_length(len: usize, exp: &Expected) -> Self {
Error::custom(format_args!("invalid length {}, expected {}", len, exp)) Error::custom(format_args!("invalid length {}, expected {}", len, exp))
} }
/// Raised when a `Deserialize` enum type received a variant with an /// Raised when a `Deserialize` enum type received a variant with an
/// unrecognized name. /// unrecognized name.
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() { if expected.is_empty() {
Error::custom(format_args!("unknown variant `{}`, there are no variants", Error::custom(format_args!("unknown variant `{}`, there are no variants",
variant)) variant))
} else { } else {
Error::custom(format_args!("unknown variant `{}`, expected {}", Error::custom(format_args!("unknown variant `{}`, expected {}",
variant, variant,
OneOf { names: expected })) 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 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 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 more than one of the
/// same field.
fn duplicate_field(field: &'static str) -> Self {
Error::custom(format_args!("duplicate field `{}`", field))
}
} }
#[cfg(feature = "std")]
declare_error_trait!(Error: Sized + error::Error);
#[cfg(not(feature = "std"))]
declare_error_trait!(Error: Sized);
/// `Unexpected` represents an unexpected invocation of any one of the `Visitor` /// `Unexpected` represents an unexpected invocation of any one of the `Visitor`
/// trait methods. /// trait methods.
/// ///
+1 -8
View File
@@ -21,8 +21,6 @@ use collections::string::ToString;
use core::hash::Hash; use core::hash::Hash;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error; use std::error;
#[cfg(not(feature = "std"))]
use error;
use core::fmt::{self, Display}; use core::fmt::{self, Display};
use core::iter::{self, Iterator}; use core::iter::{self, Iterator};
@@ -67,16 +65,11 @@ impl Display for Error {
} }
} }
#[cfg(feature = "std")]
impl error::Error for Error { impl error::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))]
fn description(&self) -> &str { fn description(&self) -> &str {
&self.err &self.err
} }
#[cfg(not(any(feature = "std", feature = "collections")))]
fn description(&self) -> &str {
"Serde deserialization error"
}
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
-17
View File
@@ -1,17 +0,0 @@
//! A stand-in for `std::error`
use core::fmt::{Debug, Display};
/// A stand-in for `std::error::Error`, which requires no allocation.
pub trait Error: Debug + Display {
/// A short description of the error.
///
/// The description should not contain newlines or sentence-ending
/// punctuation, to facilitate embedding in larger user-facing
/// strings.
fn description(&self) -> &str;
/// The lower-level cause of this error, if any.
fn cause(&self) -> Option<&Error> {
None
}
}
-2
View File
@@ -99,8 +99,6 @@ pub mod de;
#[doc(hidden)] #[doc(hidden)]
pub mod iter; pub mod iter;
pub mod ser; pub mod ser;
#[cfg_attr(feature = "std", doc(hidden))]
pub mod error;
mod utils; mod utils;
// Generated code uses these to support no_std. Not public API. // Generated code uses these to support no_std. Not public API.
+39 -29
View File
@@ -94,8 +94,6 @@
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error; use std::error;
#[cfg(not(feature = "std"))]
use error;
#[cfg(all(feature = "collections", not(feature = "std")))] #[cfg(all(feature = "collections", not(feature = "std")))]
use collections::string::String; use collections::string::String;
@@ -117,35 +115,47 @@ pub use self::impossible::Impossible;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Trait used by `Serialize` implementations to generically construct errors macro_rules! declare_error_trait {
/// belonging to the `Serializer` against which they are currently running. (Error: Sized $(+ $($supertrait:ident)::*)*) => {
pub trait Error: Sized + error::Error { /// Trait used by `Serialize` implementations to generically construct
/// Raised when a `Serialize` implementation encounters a general error /// errors belonging to the `Serializer` against which they are
/// while serializing a type. /// currently running.
/// pub trait Error: Sized $(+ $($supertrait)::*)* {
/// The message should not be capitalized and should not end with a period. /// Raised when a `Serialize` implementation encounters a general
/// /// error while serializing a type.
/// For example, a filesystem `Path` may refuse to serialize itself if it ///
/// contains invalid UTF-8 data. /// The message should not be capitalized and should not end with a
/// /// period.
/// ```rust ///
/// # use serde::ser::{Serialize, Serializer, Error}; /// For example, a filesystem `Path` may refuse to serialize itself
/// # struct Path; /// if it contains invalid UTF-8 data.
/// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } } ///
/// impl Serialize for Path { /// ```rust
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// # use serde::ser::{Serialize, Serializer, Error};
/// where S: Serializer /// # struct Path;
/// { /// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } }
/// match self.to_str() { /// impl Serialize for Path {
/// Some(s) => s.serialize(serializer), /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// None => Err(Error::custom("path contains invalid UTF-8 characters")), /// where S: Serializer
/// } /// {
/// } /// match self.to_str() {
/// } /// Some(s) => s.serialize(serializer),
/// ``` /// None => Err(Error::custom("path contains invalid UTF-8 characters")),
fn custom<T: Display>(msg: T) -> Self; /// }
/// }
/// }
/// ```
fn custom<T: Display>(msg: T) -> Self;
}
}
} }
#[cfg(feature = "std")]
declare_error_trait!(Error: Sized + error::Error);
#[cfg(not(feature = "std"))]
declare_error_trait!(Error: Sized);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A **data structure** that can be serialized into any data format supported /// A **data structure** that can be serialized into any data format supported