Skip to content

Commit c083cfd

Browse files
committed
Export std error type so downstream doesn't need "std" feature
1 parent 4cea81f commit c083cfd

4 files changed

Lines changed: 67 additions & 2 deletions

File tree

serde/src/de/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ mod utf8;
125125

126126
pub use self::ignored_any::IgnoredAny;
127127

128+
#[cfg(feature = "std")]
129+
#[doc(no_inline)]
130+
pub use std::error::Error as StdError;
131+
#[cfg(not(feature = "std"))]
132+
#[doc(no_inline)]
133+
pub use std_error::Error as StdError;
134+
128135
////////////////////////////////////////////////////////////////////////////////
129136

130137
macro_rules! declare_error_trait {
@@ -288,7 +295,7 @@ macro_rules! declare_error_trait {
288295
}
289296

290297
#[cfg(feature = "std")]
291-
declare_error_trait!(Error: Sized + error::Error);
298+
declare_error_trait!(Error: Sized + StdError);
292299

293300
#[cfg(not(feature = "std"))]
294301
declare_error_trait!(Error: Sized + Debug + Display);

serde/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ pub mod export;
250250
#[doc(hidden)]
251251
pub mod private;
252252

253+
#[cfg(not(feature = "std"))]
254+
mod std_error;
255+
253256
// Re-export #[derive(Serialize, Deserialize)].
254257
//
255258
// The reason re-exporting is not enabled by default is that disabling it would

serde/src/ser/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ mod impossible;
114114

115115
pub use self::impossible::Impossible;
116116

117+
#[cfg(feature = "std")]
118+
#[doc(no_inline)]
119+
pub use std::error::Error as StdError;
120+
#[cfg(not(feature = "std"))]
121+
#[doc(no_inline)]
122+
pub use std_error::Error as StdError;
123+
117124
////////////////////////////////////////////////////////////////////////////////
118125

119126
macro_rules! declare_error_trait {
@@ -172,7 +179,7 @@ macro_rules! declare_error_trait {
172179
}
173180

174181
#[cfg(feature = "std")]
175-
declare_error_trait!(Error: Sized + error::Error);
182+
declare_error_trait!(Error: Sized + StdError);
176183

177184
#[cfg(not(feature = "std"))]
178185
declare_error_trait!(Error: Sized + Debug + Display);

serde/src/std_error.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use lib::{Debug, Display};
2+
3+
/// Either a re-export of std::error::Error or a new identical trait, depending
4+
/// on whether Serde's "std" feature is enabled.
5+
///
6+
/// Serde's error traits [`serde::ser::Error`] and [`serde::de::Error`] require
7+
/// [`std::error::Error`] as a supertrait, but only when Serde is built with
8+
/// "std" enabled. Data formats that don't care about no\_std support should
9+
/// generally provide their error types with a `std::error::Error` impl
10+
/// directly:
11+
///
12+
/// ```edition2018
13+
/// #[derive(Debug)]
14+
/// struct MySerError {...}
15+
///
16+
/// impl serde::ser::Error for MySerError {...}
17+
///
18+
/// impl std::fmt::Display for MySerError {...}
19+
///
20+
/// // We don't support no_std!
21+
/// impl std::error::Error for MySerError {}
22+
/// ```
23+
///
24+
/// Data formats that *do* support no\_std may either have a "std" feature of
25+
/// their own:
26+
///
27+
/// ```toml
28+
/// [features]
29+
/// std = ["serde/std"]
30+
/// ```
31+
///
32+
/// ```edition2018
33+
/// #[cfg(feature = "std")]
34+
/// impl std::error::Error for MySerError {}
35+
/// ```
36+
///
37+
/// ... or else provide the std Error impl unconditionally via Serde's
38+
/// re-export:
39+
///
40+
/// ```edition2018
41+
/// impl serde::ser::StdError for MySerError {}
42+
/// ```
43+
pub trait Error: Debug + Display {
44+
/// The underlying cause of this error, if any.
45+
fn source(&self) -> Option<&(Error + 'static)> {
46+
None
47+
}
48+
}

0 commit comments

Comments
 (0)