#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
macro_rules! with_std { ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*) }
macro_rules! without_std { ($($i:item)*) => ($(#[cfg(not(feature = "std"))]$i)*) }
mod backtrace;
mod compat;
mod context;
mod result_ext;
use core::any::TypeId;
use core::fmt::{Debug, Display};
pub use backtrace::Backtrace;
pub use compat::Compat;
pub use context::Context;
pub use result_ext::ResultExt;
#[cfg(feature = "derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate failure_derive;
#[cfg(feature = "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;
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 }
}
fn causes(&self) -> Causes where Self: Sized {
Causes { fail: Some(self) }
}
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 root_cause(&self) -> &Fail {
find_root_cause(self)
}
pub fn causes(&self) -> Causes {
Causes { fail: Some(self) }
}
}
#[cfg(feature = "std")]
impl<E: StdError + Send + Sync + 'static> Fail for E {}
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
}