#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
#![deny(warnings)]
#![cfg_attr(feature = "small-error", feature(extern_types, allocator_api))]
macro_rules! with_std { ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*) }
macro_rules! without_std { ($($i:item)*) => ($(#[cfg(not(feature = "std"))]$i)*) }
#[doc(hidden)]
pub extern crate core as _core;
mod as_fail;
mod backtrace;
#[cfg(feature = "std")]
mod box_std;
mod compat;
mod context;
mod result_ext;
use core::any::TypeId;
use core::fmt::{Debug, Display};
pub use as_fail::AsFail;
pub use backtrace::Backtrace;
pub use compat::Compat;
pub use context::Context;
pub use result_ext::ResultExt;
#[cfg(feature = "failure_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate failure_derive;
#[cfg(feature = "failure_derive")]
#[doc(hidden)]
pub use failure_derive::*;
with_std! {
extern crate core;
mod sync_failure;
pub use sync_failure::SyncFailure;
mod error;
use std::error::Error as StdError;
pub use error::Error;
pub type Fallible<T> = Result<T, Error>;
mod macros;
mod error_message;
pub use error_message::err_msg;
}
pub trait Fail: Display + Debug + Send + Sync + 'static {
fn cause(&self) -> Option<&Fail> {
None
}
fn backtrace(&self) -> Option<&Backtrace> {
None
}
fn context<D>(self, context: D) -> Context<D>
where
D: Display + Send + Sync + 'static,
Self: Sized,
{
Context::with_err(context, self)
}
fn compat(self) -> Compat<Self>
where
Self: Sized,
{
Compat { error: self }
}
#[doc(hidden)]
#[deprecated(since = "0.1.2", note = "please use the 'iter_chain()' method instead")]
fn causes(&self) -> Causes
where
Self: Sized,
{
Causes { fail: Some(self) }
}
#[doc(hidden)]
#[deprecated(
since = "0.1.2",
note = "please use the 'find_root_cause()' method instead"
)]
fn root_cause(&self) -> &Fail
where
Self: Sized,
{
find_root_cause(self)
}
#[doc(hidden)]
fn __private_get_type_id__(&self) -> TypeId {
TypeId::of::<Self>()
}
}
impl Fail {
pub fn downcast_ref<T: Fail>(&self) -> Option<&T> {
if self.__private_get_type_id__() == TypeId::of::<T>() {
unsafe { Some(&*(self as *const Fail as *const T)) }
} else {
None
}
}
pub fn downcast_mut<T: Fail>(&mut self) -> Option<&mut T> {
if self.__private_get_type_id__() == TypeId::of::<T>() {
unsafe { Some(&mut *(self as *mut Fail as *mut T)) }
} else {
None
}
}
pub fn find_root_cause(&self) -> &Fail {
find_root_cause(self)
}
pub fn iter_causes(&self) -> Causes {
Causes { fail: self.cause() }
}
pub fn iter_chain(&self) -> Causes {
Causes { fail: Some(self) }
}
#[deprecated(
since = "0.1.2",
note = "please use the 'find_root_cause()' method instead"
)]
pub fn root_cause(&self) -> &Fail {
find_root_cause(self)
}
#[deprecated(since = "0.1.2", note = "please use the 'iter_chain()' method instead")]
pub fn causes(&self) -> Causes {
Causes { fail: Some(self) }
}
}
#[cfg(feature = "std")]
impl<E: StdError + Send + Sync + 'static> Fail for E {}
#[cfg(feature = "std")]
impl Fail for Box<Fail> {
fn cause(&self) -> Option<&Fail> {
(**self).cause()
}
fn backtrace(&self) -> Option<&Backtrace> {
(**self).backtrace()
}
}
pub struct Causes<'f> {
fail: Option<&'f Fail>,
}
impl<'f> Iterator for Causes<'f> {
type Item = &'f Fail;
fn next(&mut self) -> Option<&'f Fail> {
self.fail.map(|fail| {
self.fail = fail.cause();
fail
})
}
}
fn find_root_cause(mut fail: &Fail) -> &Fail {
while let Some(cause) = fail.cause() {
fail = cause;
}
fail
}