-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
33 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,199 +1,47 @@ | ||
#![allow(missing_docs)] | ||
|
||
use core::fmt::{Debug, Display}; | ||
|
||
/// `Error` is a trait representing the basic expectations for error values, | ||
/// i.e., values of type `E` in `Result<T, E>`. Errors must describe | ||
/// themselves through the `Display` and `Debug` traits, and may provide | ||
/// cause chain information: | ||
/// | ||
/// The [`source`] method is generally used when errors cross "abstraction | ||
/// boundaries". If one module must report an error that is caused by an error | ||
/// from a lower-level module, it can allow access to that error via the | ||
/// [`source`] method. This makes it possible for the high-level module to | ||
/// provide its own errors while also revealing some of the implementation for | ||
/// debugging via [`source`] chains. | ||
/// | ||
/// [`source`]: trait.Error.html#method.source | ||
pub trait Error: Debug + Display { | ||
/// **This method is soft-deprecated.** | ||
/// | ||
/// Although using it won’t cause compilation warning, | ||
/// new code should use `Display` instead | ||
/// and new `impl`s can omit it. | ||
/// | ||
/// To obtain error description as a string, use `to_string()`. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// match "xc".parse::<u32>() { | ||
/// Err(e) => { | ||
/// // Print `e` itself, not `e.description()`. | ||
/// println!("Error: {}", e); | ||
/// } | ||
/// _ => println!("No error"), | ||
/// } | ||
/// ``` | ||
fn description(&self) -> &str { | ||
"description() is deprecated; use Display" | ||
} | ||
|
||
/// The lower-level cause of this error, if any. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// use snafu::Error; | ||
/// use core::fmt; | ||
/// | ||
/// #[derive(Debug)] | ||
/// struct SuperError { | ||
/// side: SuperErrorSideKick, | ||
/// } | ||
/// | ||
/// impl fmt::Display for SuperError { | ||
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
/// write!(f, "SuperError is here!") | ||
/// } | ||
/// } | ||
/// | ||
/// impl Error for SuperError { | ||
/// fn description(&self) -> &str { | ||
/// "I'm the superhero of errors" | ||
/// } | ||
/// | ||
/// fn cause(&self) -> Option<&dyn Error> { | ||
/// Some(&self.side) | ||
/// } | ||
/// } | ||
/// | ||
/// #[derive(Debug)] | ||
/// struct SuperErrorSideKick; | ||
/// | ||
/// impl fmt::Display for SuperErrorSideKick { | ||
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
/// write!(f, "SuperErrorSideKick is here!") | ||
/// } | ||
/// } | ||
/// | ||
/// impl Error for SuperErrorSideKick { | ||
/// fn description(&self) -> &str { | ||
/// "I'm SuperError side kick" | ||
/// } | ||
/// } | ||
/// | ||
/// fn get_super_error() -> Result<(), SuperError> { | ||
/// Err(SuperError { side: SuperErrorSideKick }) | ||
/// } | ||
/// | ||
/// fn main() { | ||
/// match get_super_error() { | ||
/// Err(e) => { | ||
/// println!("Error: {}", e.description()); | ||
/// println!("Caused by: {}", e.cause().unwrap()); | ||
/// } | ||
/// _ => println!("No error"), | ||
/// } | ||
/// } | ||
/// ``` | ||
fn cause(&self) -> Option<&dyn Error> { | ||
fn cause(&self) -> Option<&Error> { | ||
self.source() | ||
} | ||
|
||
/// The lower-level source of this error, if any. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// use snafu::Error; | ||
/// use core::fmt; | ||
/// | ||
/// #[derive(Debug)] | ||
/// struct SuperError { | ||
/// side: SuperErrorSideKick, | ||
/// } | ||
/// | ||
/// impl fmt::Display for SuperError { | ||
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
/// write!(f, "SuperError is here!") | ||
/// } | ||
/// } | ||
/// | ||
/// impl Error for SuperError { | ||
/// fn description(&self) -> &str { | ||
/// "I'm the superhero of errors" | ||
/// } | ||
/// | ||
/// fn source(&self) -> Option<&(dyn Error + 'static)> { | ||
/// Some(&self.side) | ||
/// } | ||
/// } | ||
/// | ||
/// #[derive(Debug)] | ||
/// struct SuperErrorSideKick; | ||
/// | ||
/// impl fmt::Display for SuperErrorSideKick { | ||
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
/// write!(f, "SuperErrorSideKick is here!") | ||
/// } | ||
/// } | ||
/// | ||
/// impl Error for SuperErrorSideKick { | ||
/// fn description(&self) -> &str { | ||
/// "I'm SuperError side kick" | ||
/// } | ||
/// } | ||
/// | ||
/// fn get_super_error() -> Result<(), SuperError> { | ||
/// Err(SuperError { side: SuperErrorSideKick }) | ||
/// } | ||
/// | ||
/// fn main() { | ||
/// match get_super_error() { | ||
/// Err(e) => { | ||
/// println!("Error: {}", e.description()); | ||
/// println!("Caused by: {}", e.source().unwrap()); | ||
/// } | ||
/// _ => println!("No error"), | ||
/// } | ||
/// } | ||
/// ``` | ||
fn source(&self) -> Option<&(dyn Error + 'static)> { | ||
fn source(&self) -> Option<&(Error + 'static)> { | ||
None | ||
} | ||
} | ||
|
||
impl Error for core::str::ParseBoolError { | ||
fn description(&self) -> &str { | ||
"failed to parse bool" | ||
} | ||
} | ||
impl Error for core::str::Utf8Error { | ||
fn description(&self) -> &str { | ||
"invalid utf-8: corrupt contents" | ||
} | ||
} | ||
impl Error for core::num::ParseIntError {} | ||
impl Error for core::num::TryFromIntError {} | ||
impl Error for core::array::TryFromSliceError {} | ||
impl Error for core::num::ParseFloatError {} | ||
impl Error for core::fmt::Error { | ||
fn description(&self) -> &str { | ||
"an error occurred when formatting an argument" | ||
} | ||
} | ||
impl Error for core::cell::BorrowError { | ||
fn description(&self) -> &str { | ||
"already mutably borrowed" | ||
} | ||
} | ||
impl Error for core::cell::BorrowMutError { | ||
fn description(&self) -> &str { | ||
"already borrowed" | ||
macro_rules! impl_error { | ||
($($e:path),*) => { | ||
$( | ||
impl Error for $e {} | ||
)* | ||
} | ||
} | ||
impl Error for core::char::CharTryFromError { | ||
fn description(&self) -> &str { | ||
"converted integer out of range for `char`" | ||
} | ||
} | ||
impl Error for core::char::ParseCharError {} | ||
|
||
// All errors supported by our minimum suported Rust version can be supported by | ||
// default. | ||
impl_error![ | ||
core::str::ParseBoolError, // 1.0 | ||
core::str::Utf8Error, // 1.0 | ||
core::num::ParseIntError, // 1.0 | ||
core::num::ParseFloatError, // 1.0 | ||
core::char::DecodeUtf16Error, // 1.9 | ||
core::fmt::Error, // 1.11 | ||
core::cell::BorrowMutError, // 1.13 | ||
core::cell::BorrowError // 1.13 | ||
]; | ||
|
||
#[cfg(feature = "rust_1_30")] | ||
impl_error![core::char::ParseCharError]; // 1.20 | ||
|
||
// We can gate these together with std futures. | ||
#[cfg(feature = "unstable-futures")] | ||
impl_error![ | ||
core::num::TryFromIntError, // 1.34 | ||
core::array::TryFromSliceError, // 1.34 | ||
core::char::CharTryFromError // 1.34 | ||
]; |