Skip to content

Commit

Permalink
Merge pull request #1620 from dtolnay/error
Browse files Browse the repository at this point in the history
Export std error type so no_std data formats don't need a "std" feature
  • Loading branch information
dtolnay committed Sep 8, 2019
2 parents 4cea81f + c083cfd commit 3343885
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
9 changes: 8 additions & 1 deletion serde/src/de/mod.rs
Expand Up @@ -125,6 +125,13 @@ mod utf8;

pub use self::ignored_any::IgnoredAny;

#[cfg(feature = "std")]
#[doc(no_inline)]
pub use std::error::Error as StdError;
#[cfg(not(feature = "std"))]
#[doc(no_inline)]
pub use std_error::Error as StdError;

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

macro_rules! declare_error_trait {
Expand Down Expand Up @@ -288,7 +295,7 @@ macro_rules! declare_error_trait {
}

#[cfg(feature = "std")]
declare_error_trait!(Error: Sized + error::Error);
declare_error_trait!(Error: Sized + StdError);

#[cfg(not(feature = "std"))]
declare_error_trait!(Error: Sized + Debug + Display);
Expand Down
3 changes: 3 additions & 0 deletions serde/src/lib.rs
Expand Up @@ -250,6 +250,9 @@ pub mod export;
#[doc(hidden)]
pub mod private;

#[cfg(not(feature = "std"))]
mod std_error;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
Expand Down
9 changes: 8 additions & 1 deletion serde/src/ser/mod.rs
Expand Up @@ -114,6 +114,13 @@ mod impossible;

pub use self::impossible::Impossible;

#[cfg(feature = "std")]
#[doc(no_inline)]
pub use std::error::Error as StdError;
#[cfg(not(feature = "std"))]
#[doc(no_inline)]
pub use std_error::Error as StdError;

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

macro_rules! declare_error_trait {
Expand Down Expand Up @@ -172,7 +179,7 @@ macro_rules! declare_error_trait {
}

#[cfg(feature = "std")]
declare_error_trait!(Error: Sized + error::Error);
declare_error_trait!(Error: Sized + StdError);

#[cfg(not(feature = "std"))]
declare_error_trait!(Error: Sized + Debug + Display);
Expand Down
48 changes: 48 additions & 0 deletions serde/src/std_error.rs
@@ -0,0 +1,48 @@
use lib::{Debug, Display};

/// Either a re-export of std::error::Error or a new identical trait, depending
/// on whether Serde's "std" feature is enabled.
///
/// Serde's error traits [`serde::ser::Error`] and [`serde::de::Error`] require
/// [`std::error::Error`] as a supertrait, but only when Serde is built with
/// "std" enabled. Data formats that don't care about no\_std support should
/// generally provide their error types with a `std::error::Error` impl
/// directly:
///
/// ```edition2018
/// #[derive(Debug)]
/// struct MySerError {...}
///
/// impl serde::ser::Error for MySerError {...}
///
/// impl std::fmt::Display for MySerError {...}
///
/// // We don't support no_std!
/// impl std::error::Error for MySerError {}
/// ```
///
/// Data formats that *do* support no\_std may either have a "std" feature of
/// their own:
///
/// ```toml
/// [features]
/// std = ["serde/std"]
/// ```
///
/// ```edition2018
/// #[cfg(feature = "std")]
/// impl std::error::Error for MySerError {}
/// ```
///
/// ... or else provide the std Error impl unconditionally via Serde's
/// re-export:
///
/// ```edition2018
/// impl serde::ser::StdError for MySerError {}
/// ```
pub trait Error: Debug + Display {
/// The underlying cause of this error, if any.
fn source(&self) -> Option<&(Error + 'static)> {
None
}
}

0 comments on commit 3343885

Please sign in to comment.