#![allow(unknown_lints, bare_trait_objects)]
#![deny(missing_docs)]
#[cfg(feature = "backtraces")]
extern crate backtrace;
#[cfg(feature = "backtraces")]
mod backtrace_shim;
#[cfg(feature = "backtraces")]
pub use backtrace_shim::*;
#[cfg(feature = "futures-01")]
extern crate futures01 as futures01_crate;
#[cfg(feature = "futures-01")]
pub mod futures01;
#[cfg(feature = "unstable-futures")]
extern crate futures_core;
#[cfg(feature = "unstable-futures")]
extern crate pin_project;
#[cfg(feature = "unstable-futures")]
pub mod futures;
#[cfg(feature = "rust_1_30")]
extern crate snafu_derive;
#[cfg(feature = "rust_1_30")]
pub use snafu_derive::Snafu;
#[cfg(feature = "rust_1_30")]
extern crate doc_comment;
#[cfg(feature = "rust_1_30")]
macro_rules! generate_guide {
(pub mod $name:ident; $($rest:tt)*) => {
generate_guide!(@gen ".", pub mod $name { } $($rest)*);
};
(pub mod $name:ident { $($children:tt)* } $($rest:tt)*) => {
generate_guide!(@gen ".", pub mod $name { $($children)* } $($rest)*);
};
(@gen $prefix:expr, ) => {};
(@gen $prefix:expr, pub mod $name:ident; $($rest:tt)*) => {
generate_guide!(@gen $prefix, pub mod $name { } $($rest)*);
};
(@gen $prefix:expr, pub mod $name:ident { $($children:tt)* } $($rest:tt)*) => {
doc_comment::doc_comment! {
include_str!(concat!($prefix, "/", stringify!($name), ".md")),
pub mod $name {
generate_guide!(@gen concat!($prefix, "/", stringify!($name)), $($children)*);
}
}
generate_guide!(@gen $prefix, $($rest)*);
};
}
#[cfg(feature = "rust_1_30")]
generate_guide! {
pub mod guide {
pub mod attributes;
pub mod comparison {
pub mod failure;
}
pub mod compatibility;
pub mod feature_flags;
pub mod generics;
pub mod opaque;
pub mod philosophy;
pub mod the_macro;
pub mod upgrading;
}
}
#[cfg(feature = "rust_1_30")]
doc_comment::doctest!("../README.md", readme_tests);
use std::error;
#[macro_export]
macro_rules! ensure {
($predicate:expr, $context_selector:expr) => {
if !$predicate {
return $context_selector.fail();
}
};
}
pub trait ResultExt<T, E>: Sized {
fn context<C, E2>(self, context: C) -> Result<T, E2>
where
C: IntoError<E2, Source = E>,
E2: std::error::Error + ErrorCompat;
fn with_context<F, C, E2>(self, context: F) -> Result<T, E2>
where
F: FnOnce() -> C,
C: IntoError<E2, Source = E>,
E2: std::error::Error + ErrorCompat;
#[doc(hidden)]
#[deprecated(since = "0.4.0", note = "use ResultExt::context instead")]
fn eager_context<C, E2>(self, context: C) -> Result<T, E2>
where
C: IntoError<E2, Source = E>,
E2: std::error::Error + ErrorCompat,
{
self.context(context)
}
#[doc(hidden)]
#[deprecated(since = "0.4.0", note = "use ResultExt::with_context instead")]
fn with_eager_context<F, C, E2>(self, context: F) -> Result<T, E2>
where
F: FnOnce() -> C,
C: IntoError<E2, Source = E>,
E2: std::error::Error + ErrorCompat,
{
self.with_context(context)
}
}
impl<T, E> ResultExt<T, E> for std::result::Result<T, E> {
fn context<C, E2>(self, context: C) -> Result<T, E2>
where
C: IntoError<E2, Source = E>,
E2: std::error::Error + ErrorCompat,
{
self.map_err(|error| context.into_error(error))
}
fn with_context<F, C, E2>(self, context: F) -> Result<T, E2>
where
F: FnOnce() -> C,
C: IntoError<E2, Source = E>,
E2: std::error::Error + ErrorCompat,
{
self.map_err(|error| {
let context = context();
context.into_error(error)
})
}
}
pub struct NoneError;
pub trait OptionExt<T>: Sized {
fn context<C, E>(self, context: C) -> Result<T, E>
where
C: IntoError<E, Source = NoneError>,
E: std::error::Error + ErrorCompat;
fn with_context<F, C, E>(self, context: F) -> Result<T, E>
where
F: FnOnce() -> C,
C: IntoError<E, Source = NoneError>,
E: std::error::Error + ErrorCompat;
#[doc(hidden)]
#[deprecated(since = "0.4.0", note = "use OptionExt::context instead")]
fn eager_context<C, E>(self, context: C) -> Result<T, E>
where
C: IntoError<E, Source = NoneError>,
E: std::error::Error + ErrorCompat,
{
self.context(context).map_err(Into::into)
}
#[doc(hidden)]
#[deprecated(since = "0.4.0", note = "use OptionExt::with_context instead")]
fn with_eager_context<F, C, E>(self, context: F) -> Result<T, E>
where
F: FnOnce() -> C,
C: IntoError<E, Source = NoneError>,
E: std::error::Error + ErrorCompat,
{
self.with_context(context).map_err(Into::into)
}
}
impl<T> OptionExt<T> for Option<T> {
fn context<C, E>(self, context: C) -> Result<T, E>
where
C: IntoError<E, Source = NoneError>,
E: std::error::Error + ErrorCompat,
{
self.ok_or_else(|| context.into_error(NoneError))
}
fn with_context<F, C, E>(self, context: F) -> Result<T, E>
where
F: FnOnce() -> C,
C: IntoError<E, Source = NoneError>,
E: std::error::Error + ErrorCompat,
{
self.ok_or_else(|| context().into_error(NoneError))
}
}
pub trait ErrorCompat {
#[cfg(feature = "backtraces")]
fn backtrace(&self) -> Option<&Backtrace> {
None
}
}
impl<'a, E> ErrorCompat for &'a E
where
E: ErrorCompat,
{
#[cfg(feature = "backtraces")]
fn backtrace(&self) -> Option<&Backtrace> {
(**self).backtrace()
}
}
impl<E> ErrorCompat for Box<E>
where
E: ErrorCompat,
{
#[cfg(feature = "backtraces")]
fn backtrace(&self) -> Option<&Backtrace> {
(**self).backtrace()
}
}
pub trait AsErrorSource {
fn as_error_source(&self) -> &(error::Error + 'static);
}
impl AsErrorSource for error::Error + 'static {
fn as_error_source(&self) -> &(error::Error + 'static) {
self
}
}
impl AsErrorSource for error::Error + Send + 'static {
fn as_error_source(&self) -> &(error::Error + 'static) {
self
}
}
impl AsErrorSource for error::Error + Sync + 'static {
fn as_error_source(&self) -> &(error::Error + 'static) {
self
}
}
impl AsErrorSource for error::Error + Send + Sync + 'static {
fn as_error_source(&self) -> &(error::Error + 'static) {
self
}
}
impl<T: error::Error + 'static> AsErrorSource for T {
fn as_error_source(&self) -> &(error::Error + 'static) {
self
}
}
pub trait IntoError<Error>
where
Error: std::error::Error + ErrorCompat,
{
type Source;
fn into_error(self, source: Self::Source) -> Error;
}