summaryrefslogtreecommitdiffstats
path: root/third_party/rust/error-chain/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/error-chain/src/lib.rs')
-rw-r--r--third_party/rust/error-chain/src/lib.rs824
1 files changed, 824 insertions, 0 deletions
diff --git a/third_party/rust/error-chain/src/lib.rs b/third_party/rust/error-chain/src/lib.rs
new file mode 100644
index 0000000000..43d2d5f479
--- /dev/null
+++ b/third_party/rust/error-chain/src/lib.rs
@@ -0,0 +1,824 @@
+#![deny(missing_docs)]
+#![doc(html_root_url = "https://docs.rs/error-chain/0.12.4")]
+
+//! A library for consistent and reliable error handling
+//!
+//! error-chain makes it easy to take full advantage of Rust's
+//! powerful error handling features without the overhead of
+//! maintaining boilerplate error types and conversions. It implements
+//! an opinionated strategy for defining your own error types, as well
+//! as conversions from others' error types.
+//!
+//! ## Quick start
+//!
+//! If you just want to set up your new project with error-chain,
+//! follow the [quickstart.rs] template, and read this [intro]
+//! to error-chain.
+//!
+//! [quickstart.rs]: https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs
+//! [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
+//!
+//! ## Why error chain?
+//!
+//! * error-chain is easy to configure. Handle errors robustly with minimal
+//! effort.
+//! * Basic error handling requires no maintenance of custom error types
+//! nor the [`From`] conversions that make `?` work.
+//! * error-chain scales from simple error handling strategies to more
+//! rigorous. Return formatted strings for simple errors, only
+//! introducing error variants and their strong typing as needed for
+//! advanced error recovery.
+//! * error-chain makes it trivial to correctly manage the [cause] of
+//! the errors generated by your own code. This is the "chaining"
+//! in "error-chain".
+//!
+//! [cause]: https://doc.rust-lang.org/std/error/trait.Error.html#method.cause
+//!
+//! ## Principles of error-chain
+//!
+//! error-chain is based on the following principles:
+//!
+//! * No error should ever be discarded. This library primarily
+//! makes it easy to "chain" errors with the [`chain_err`] method.
+//! * Introducing new errors is trivial. Simple errors can be introduced
+//! at the error site with just a string.
+//! * Handling errors is possible with pattern matching.
+//! * Conversions between error types are done in an automatic and
+//! consistent way - [`From`] conversion behavior is never specified
+//! explicitly.
+//! * Errors implement [`Send`].
+//! * Errors can carry backtraces.
+//!
+//! Similar to other libraries like [error-type] and [quick-error],
+//! this library introduces the error chaining mechanism originally
+//! employed by Cargo. The [`error_chain!`] macro declares the types
+//! and implementation boilerplate necessary for fulfilling a
+//! particular error-handling strategy. Most importantly it defines a
+//! custom error type (called [`Error`] by convention) and the [`From`]
+//! conversions that let the `?` operator work.
+//!
+//! This library differs in a few ways from previous error libs:
+//!
+//! * Instead of defining the custom [`Error`] type as an enum, it is a
+//! struct containing an [`ErrorKind`][] (which defines the
+//! [`description`] and [`display_chain`] methods for the error), an opaque,
+//! optional, boxed [`std::error::Error`]` + `[`Send`]` + 'static` object
+//! (which defines the [`cause`], and establishes the links in the
+//! error chain), and a [`Backtrace`].
+//! * The macro also defines a [`ResultExt`] trait that defines a
+//! [`chain_err`] method. This method on all [`std::error::Error`]` + `[`Send`]` + 'static`
+//! types extends the error chain by boxing the current
+//! error into an opaque object and putting it inside a new concrete
+//! error.
+//! * It provides automatic [`From`] conversions between other error types
+//! defined by the [`error_chain!`] that preserve type information,
+//! and facilitate seamless error composition and matching of composed
+//! errors.
+//! * It provides automatic [`From`] conversions between any other error
+//! type that hides the type of the other error in the [`cause`] box.
+//! * If `RUST_BACKTRACE` is enabled, it collects a single backtrace at
+//! the earliest opportunity and propagates it down the stack through
+//! [`From`] and [`ResultExt`] conversions.
+//!
+//! To accomplish its goals it makes some tradeoffs:
+//!
+//! * The split between the [`Error`] and [`ErrorKind`] types can make it
+//! slightly more cumbersome to instantiate new (unchained) errors,
+//! requiring an [`Into`] or [`From`] conversion; as well as slightly
+//! more cumbersome to match on errors with another layer of types
+//! to match.
+//! * Because the error type contains [`std::error::Error`]` + `[`Send`]` + 'static` objects,
+//! it can't implement [`PartialEq`] for easy comparisons.
+//!
+//! ## Declaring error types
+//!
+//! Generally, you define one family of error types per crate, though
+//! it's also perfectly fine to define error types on a finer-grained
+//! basis, such as per module.
+//!
+//! Assuming you are using crate-level error types, typically you will
+//! define an `errors` module and inside it call [`error_chain!`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod other_error {
+//! error_chain! {}
+//! }
+//!
+//! error_chain! {
+//! // The type defined for this error. These are the conventional
+//! // and recommended names, but they can be arbitrarily chosen.
+//! //
+//! // It is also possible to leave this section out entirely, or
+//! // leave it empty, and these names will be used automatically.
+//! types {
+//! Error, ErrorKind, ResultExt, Result;
+//! }
+//!
+//! // Without the `Result` wrapper:
+//! //
+//! // types {
+//! // Error, ErrorKind, ResultExt;
+//! // }
+//!
+//! // Automatic conversions between this error chain and other
+//! // error chains. In this case, it will e.g. generate an
+//! // `ErrorKind` variant called `Another` which in turn contains
+//! // the `other_error::ErrorKind`, with conversions from
+//! // `other_error::Error`.
+//! //
+//! // Optionally, some attributes can be added to a variant.
+//! //
+//! // This section can be empty.
+//! links {
+//! Another(other_error::Error, other_error::ErrorKind) #[cfg(unix)];
+//! }
+//!
+//! // Automatic conversions between this error chain and other
+//! // error types not defined by the `error_chain!`. These will be
+//! // wrapped in a new error with, in the first case, the
+//! // `ErrorKind::Fmt` variant. The description and cause will
+//! // forward to the description and cause of the original error.
+//! //
+//! // Optionally, some attributes can be added to a variant.
+//! //
+//! // This section can be empty.
+//! foreign_links {
+//! Fmt(::std::fmt::Error);
+//! Io(::std::io::Error) #[cfg(unix)];
+//! }
+//!
+//! // Define additional `ErrorKind` variants. Define custom responses with the
+//! // `description` and `display` calls.
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//!
+//! // You can also add commas after description/display.
+//! // This may work better with some editor auto-indentation modes:
+//! UnknownToolchainVersion(v: String) {
+//! description("unknown toolchain version"), // note the ,
+//! display("unknown toolchain version: '{}'", v), // trailing comma is allowed
+//! }
+//! }
+//!
+//! // If this annotation is left off, a variant `Msg(s: String)` will be added, and `From`
+//! // impls will be provided for `String` and `&str`
+//! skip_msg_variant
+//! }
+//!
+//! # fn main() {}
+//! ```
+//!
+//! Each section, `types`, `links`, `foreign_links`, and `errors` may
+//! be omitted if it is empty.
+//!
+//! This populates the module with a number of definitions,
+//! the most important of which are the [`Error`] type
+//! and the [`ErrorKind`] type. An example of generated code can be found in the
+//! [example_generated](example_generated/index.html) module.
+//!
+//! ## Returning new errors
+//!
+//! Introducing new error chains, with a string message:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! fn foo() -> Result<()> {
+//! Err("foo error!".into())
+//! }
+//! ```
+//!
+//! Introducing new error chains, with an [`ErrorKind`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! error_chain! {
+//! errors { FooError }
+//! }
+//!
+//! fn foo() -> Result<()> {
+//! Err(ErrorKind::FooError.into())
+//! }
+//! ```
+//!
+//! Note that the return type is the typedef [`Result`], which is
+//! defined by the macro as `pub type Result<T> =
+//! ::std::result::Result<T, Error>`. Note that in both cases
+//! [`.into()`] is called to convert a type into the [`Error`] type; both
+//! strings and [`ErrorKind`] have [`From`] conversions to turn them into
+//! [`Error`].
+//!
+//! When the error is emitted behind the `?` operator, the explicit conversion
+//! isn't needed; `Err(ErrorKind)` will automatically be converted to `Err(Error)`.
+//! So the below is equivalent to the previous:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//! Ok(Err(ErrorKind::FooError)?)
+//! }
+//!
+//! fn bar() -> Result<()> {
+//! Ok(Err("bogus!")?)
+//! }
+//! ```
+//!
+//! ## The `bail!` macro
+//!
+//! The above method of introducing new errors works but is a little
+//! verbose. Instead, we can use the [`bail!`] macro, which performs an early return
+//! with conversions done automatically.
+//!
+//! With [`bail!`] the previous examples look like:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//! if true {
+//! bail!(ErrorKind::FooError);
+//! } else {
+//! Ok(())
+//! }
+//! }
+//!
+//! fn bar() -> Result<()> {
+//! if true {
+//! bail!("bogus!");
+//! } else {
+//! Ok(())
+//! }
+//! }
+//! ```
+//!
+//! ## Chaining errors
+//! error-chain supports extending an error chain by appending new errors.
+//! This can be done on a Result or on an existing Error.
+//!
+//! To extend the error chain:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! # fn do_something() -> Result<()> { unimplemented!() }
+//! # fn test() -> Result<()> {
+//! let res: Result<()> = do_something().chain_err(|| "something went wrong");
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! [`chain_err`] can be called on any [`Result`] type where the contained
+//! error type implements [`std::error::Error`]` + `[`Send`]` + 'static`, as long as
+//! the [`Result`] type's corresponding [`ResultExt`] trait is in scope. If
+//! the [`Result`] is an `Err` then [`chain_err`] evaluates the closure,
+//! which returns *some type that can be converted to [`ErrorKind`]*,
+//! boxes the original error to store as the cause, then returns a new
+//! error containing the original error.
+//!
+//! Calling [`chain_err`][Error_chain_err] on an existing [`Error`] instance has
+//! the same signature and produces the same outcome as being called on a
+//! [`Result`] matching the properties described above. This is most useful when
+//! partially handling errors using the [`map_err`] function.
+//!
+//! To chain an error directly, use [`with_chain`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! # fn do_something() -> Result<()> { unimplemented!() }
+//! # fn test() -> Result<()> {
+//! let res: Result<()> =
+//! do_something().map_err(|e| Error::with_chain(e, "something went wrong"));
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! ## Linking errors
+//!
+//! To convert an error from another error chain to this error chain:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # mod other { error_chain! {} }
+//! error_chain! {
+//! links {
+//! OtherError(other::Error, other::ErrorKind);
+//! }
+//! }
+//!
+//! fn do_other_thing() -> other::Result<()> { unimplemented!() }
+//!
+//! # fn test() -> Result<()> {
+//! let res: Result<()> = do_other_thing().map_err(|e| e.into());
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! The [`Error`] and [`ErrorKind`] types implements [`From`] for the corresponding
+//! types of all linked error chains. Linked errors do not introduce a new
+//! cause to the error chain.
+//!
+//! ## Matching errors
+//!
+//! error-chain error variants are matched with simple patterns.
+//! [`Error`] is a tuple struct and its first field is the [`ErrorKind`],
+//! making dispatching on error kinds relatively compact:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {
+//! error_chain! {
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//! }
+//! }
+//!
+//! match Error::from("error!") {
+//! Error(ErrorKind::InvalidToolchainName(_), _) => { }
+//! Error(ErrorKind::Msg(_), _) => { }
+//! _ => { }
+//! }
+//! # }
+//! ```
+//!
+//! Chained errors are also matched with (relatively) compact syntax
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod utils {
+//! error_chain! {
+//! errors {
+//! BadStuff {
+//! description("bad stuff")
+//! }
+//! }
+//! }
+//! }
+//!
+//! mod app {
+//! error_chain! {
+//! links {
+//! Utils(::utils::Error, ::utils::ErrorKind);
+//! }
+//! }
+//! }
+//!
+//!
+//! # fn main() {
+//! match app::Error::from("error!") {
+//! app::Error(app::ErrorKind::Utils(utils::ErrorKind::BadStuff), _) => { }
+//! _ => { }
+//! }
+//! # }
+//! ```
+//!
+//! ## Inspecting errors
+//!
+//! An error-chain error contains information about the error itself, a backtrace, and the chain
+//! of causing errors. For reporting purposes, this information can be accessed as follows.
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! use error_chain::ChainedError; // for e.display_chain()
+//!
+//! error_chain! {
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//! }
+//! }
+//!
+//! # fn main() {
+//! // Generate an example error to inspect:
+//! let e = "xyzzy".parse::<i32>()
+//! .chain_err(|| ErrorKind::InvalidToolchainName("xyzzy".to_string()))
+//! .unwrap_err();
+//!
+//! // Get the brief description of the error:
+//! assert_eq!(e.description(), "invalid toolchain name");
+//!
+//! // Get the display version of the error:
+//! assert_eq!(e.to_string(), "invalid toolchain name: 'xyzzy'");
+//!
+//! // Get the full cause and backtrace:
+//! println!("{}", e.display_chain().to_string());
+//! // Error: invalid toolchain name: 'xyzzy'
+//! // Caused by: invalid digit found in string
+//! // stack backtrace:
+//! // 0: 0x7fa9f684fc94 - backtrace::backtrace::libunwind::trace
+//! // at src/backtrace/libunwind.rs:53
+//! // - backtrace::backtrace::trace<closure>
+//! // at src/backtrace/mod.rs:42
+//! // 1: 0x7fa9f6850b0e - backtrace::capture::{{impl}}::new
+//! // at out/capture.rs:79
+//! // [..]
+//! # }
+//! ```
+//!
+//! The [`Error`] and [`ErrorKind`] types also allow programmatic access to these elements.
+//!
+//! ## Foreign links
+//!
+//! Errors that do not conform to the same conventions as this library
+//! can still be included in the error chain. They are considered "foreign
+//! errors", and are declared using the `foreign_links` block of the
+//! [`error_chain!`] macro. [`Error`]s are automatically created from
+//! foreign errors by the `?` operator.
+//!
+//! Foreign links and regular links have one crucial difference:
+//! [`From`] conversions for regular links *do not introduce a new error
+//! into the error chain*, while conversions for foreign links *always
+//! introduce a new error into the error chain*. So for the example
+//! above all errors deriving from the [`std::fmt::Error`] type will be
+//! presented to the user as a new [`ErrorKind`] variant, and the
+//! cause will be the original [`std::fmt::Error`] error. In contrast, when
+//! `other_error::Error` is converted to `Error` the two `ErrorKind`s
+//! are converted between each other to create a new `Error` but the
+//! old error is discarded; there is no "cause" created from the
+//! original error.
+//!
+//! ## Backtraces
+//!
+//! If the `RUST_BACKTRACE` environment variable is set to anything
+//! but ``0``, the earliest non-foreign error to be generated creates
+//! a single backtrace, which is passed through all [`From`] conversions
+//! and [`chain_err`] invocations of compatible types. To read the
+//! backtrace just call the [`backtrace`] method.
+//!
+//! Backtrace generation can be disabled by turning off the `backtrace` feature.
+//!
+//! The Backtrace contains a Vec of [`BacktraceFrame`]s that can be operated
+//! on directly. For example, to only see the files and line numbers of code
+//! within your own project.
+//!
+//! ```
+//! # #[macro_use]
+//! # extern crate error_chain;
+//! # mod errors {
+//! # error_chain! {
+//! # foreign_links {
+//! # Io(::std::io::Error);
+//! # }
+//! # }
+//! # }
+//! # use errors::*;
+//! # #[cfg(feature="backtrace")]
+//! # fn main() {
+//! if let Err(ref e) = open_file() {
+//! if let Some(backtrace) = e.backtrace() {
+//! let frames = backtrace.frames();
+//! for frame in frames.iter() {
+//! for symbol in frame.symbols().iter() {
+//! if let (Some(file), Some(lineno)) = (symbol.filename(), symbol.lineno()) {
+//! if file.display().to_string()[0..3] == "src".to_string(){
+//! println!("{}:{}", file.display().to_string(), lineno);
+//! }
+//! }
+//! }
+//! }
+//! }
+//! };
+//! # }
+//! # #[cfg(not(feature="backtrace"))]
+//! # fn main() { }
+//!
+//! fn open_file() -> Result<()> {
+//! std::fs::File::open("does_not_exist")?;
+//! Ok(())
+//! }
+//! ```
+//!
+//! ## Iteration
+//!
+//! The [`iter`] method returns an iterator over the chain of error boxes.
+//!
+//! [error-type]: https://github.com/DanielKeep/rust-error-type
+//! [quick-error]: https://github.com/tailhook/quick-error
+
+//! [`display_chain`]: trait.ChainedError.html#method.display_chain
+//! [`error_chain!`]: macro.error_chain.html
+//! [`bail!`]: macro.bail.html
+//! [`Backtrace`]: struct.Backtrace.html
+
+//! [`Error`]: example_generated/struct.Error.html
+//! [`with_chain`]: example_generated/struct.Error.html#method.with_chain
+//! [Error_chain_err]: example_generated/struct.Error.html#method.chain_err
+//! [`cause`]: example_generated/struct.Error.html#method.cause
+//! [`backtrace`]: example_generated/struct.Error.html#method.backtrace
+//! [`iter`]: example_generated/struct.Error.html#method.iter
+//! [`ErrorKind`]: example_generated/enum.ErrorKind.html
+//! [`description`]: example_generated/enum.ErrorKind.html#method.description
+//! [`Result`]: example_generated/type.Result.html
+//! [`ResultExt`]: example_generated/trait.ResultExt.html
+//! [`chain_err`]: example_generated/trait.ResultExt.html#tymethod.chain_err
+
+//! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
+//! [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
+//! [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
+//! [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
+//! [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
+//! [`std::fmt::Error`]: https://doc.rust-lang.org/std/fmt/struct.Error.html
+//! [`.into()`]: https://doc.rust-lang.org/std/convert/trait.Into.html#tymethod.into
+//! [`map_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
+//! [`BacktraceFrame`]: https://docs.rs/backtrace/0.3.2/backtrace/struct.BacktraceFrame.html
+
+use std::error;
+use std::fmt;
+use std::iter::Iterator;
+
+#[macro_use]
+mod impl_error_chain_kind;
+#[macro_use]
+mod error_chain;
+#[macro_use]
+mod quick_main;
+pub use quick_main::ExitCode;
+mod backtrace;
+#[cfg(feature = "example_generated")]
+pub mod example_generated;
+pub use backtrace::Backtrace;
+#[doc(hidden)]
+pub use backtrace::InternalBacktrace;
+
+#[derive(Debug)]
+#[allow(unknown_lints, bare_trait_objects)]
+/// Iterator over the error chain using the `Error::cause()` method.
+pub struct Iter<'a>(Option<&'a error::Error>);
+
+impl<'a> Iter<'a> {
+ /// Returns a new iterator over the error chain using `Error::cause()`.
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn new(err: Option<&'a error::Error>) -> Iter<'a> {
+ Iter(err)
+ }
+}
+
+#[allow(unknown_lints, bare_trait_objects)]
+impl<'a> Iterator for Iter<'a> {
+ type Item = &'a error::Error;
+
+ fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
+ match self.0.take() {
+ Some(e) => {
+ self.0 = match () {
+ #[cfg(not(has_error_source))]
+ () => e.cause(),
+ #[cfg(has_error_source)]
+ () => e.source(),
+ };
+ Some(e)
+ }
+ None => None,
+ }
+ }
+}
+
+/// This trait is implemented on all the errors generated by the `error_chain`
+/// macro.
+pub trait ChainedError: error::Error + Send + 'static {
+ /// Associated kind type.
+ type ErrorKind;
+
+ /// Constructs an error from a kind, and generates a backtrace.
+ fn from_kind(kind: Self::ErrorKind) -> Self
+ where
+ Self: Sized;
+
+ /// Constructs a chained error from another error and a kind, and generates a backtrace.
+ fn with_chain<E, K>(error: E, kind: K) -> Self
+ where
+ Self: Sized,
+ E: ::std::error::Error + Send + 'static,
+ K: Into<Self::ErrorKind>;
+
+ /// Returns the kind of the error.
+ fn kind(&self) -> &Self::ErrorKind;
+
+ /// Iterates over the error chain.
+ fn iter(&self) -> Iter;
+
+ /// Returns the backtrace associated with this error.
+ fn backtrace(&self) -> Option<&Backtrace>;
+
+ /// Returns an object which implements `Display` for printing the full
+ /// context of this error.
+ ///
+ /// The full cause chain and backtrace, if present, will be printed.
+ fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
+ DisplayChain(self)
+ }
+
+ /// Extends the error chain with a new entry.
+ fn chain_err<F, EK>(self, error: F) -> Self
+ where
+ F: FnOnce() -> EK,
+ EK: Into<Self::ErrorKind>;
+
+ /// Creates an error from its parts.
+ #[doc(hidden)]
+ fn new(kind: Self::ErrorKind, state: State) -> Self
+ where
+ Self: Sized;
+
+ /// Returns the first known backtrace, either from its State or from one
+ /// of the errors from `foreign_links`.
+ #[doc(hidden)]
+ #[allow(unknown_lints, bare_trait_objects)]
+ fn extract_backtrace(e: &(error::Error + Send + 'static)) -> Option<InternalBacktrace>
+ where
+ Self: Sized;
+}
+
+/// A struct which formats an error for output.
+#[derive(Debug)]
+pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
+
+impl<'a, T> fmt::Display for DisplayChain<'a, T>
+where
+ T: ChainedError,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ writeln!(fmt, "Error: {}", self.0)?;
+
+ for e in self.0.iter().skip(1) {
+ writeln!(fmt, "Caused by: {}", e)?;
+ }
+
+ if let Some(backtrace) = ChainedError::backtrace(self.0) {
+ writeln!(fmt, "{:?}", backtrace)?;
+ }
+
+ Ok(())
+ }
+}
+
+/// Common state between errors.
+#[derive(Debug)]
+#[doc(hidden)]
+#[allow(unknown_lints, bare_trait_objects)]
+pub struct State {
+ /// Next error in the error chain.
+ pub next_error: Option<Box<error::Error + Send>>,
+ /// Backtrace for the current error.
+ pub backtrace: InternalBacktrace,
+}
+
+impl Default for State {
+ fn default() -> State {
+ State {
+ next_error: None,
+ backtrace: InternalBacktrace::new(),
+ }
+ }
+}
+
+impl State {
+ /// Creates a new State type
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
+ let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new);
+ State {
+ next_error: Some(e),
+ backtrace: backtrace,
+ }
+ }
+
+ /// Returns the inner backtrace if present.
+ pub fn backtrace(&self) -> Option<&Backtrace> {
+ self.backtrace.as_backtrace()
+ }
+}
+
+/// Exits a function early with an error
+///
+/// The `bail!` macro provides an easy way to exit a function.
+/// `bail!(expr)` is equivalent to writing.
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let expr = "";
+/// return Err(expr.into());
+/// # }
+/// ```
+///
+/// And as shorthand it takes a formatting string a la `println!`:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let n = 0;
+/// bail!("bad number: {}", n);
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// Bailing on a custom error:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! {
+/// errors { FooError }
+/// }
+///
+/// fn foo() -> Result<()> {
+/// if bad_condition() {
+/// bail!(ErrorKind::FooError);
+/// }
+///
+/// Ok(())
+/// }
+///
+/// # fn bad_condition() -> bool { true }
+/// ```
+///
+/// Bailing on a formatted string:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! { }
+///
+/// fn foo() -> Result<()> {
+/// if let Some(bad_num) = bad_condition() {
+/// bail!("so bad: {}", bad_num);
+/// }
+///
+/// Ok(())
+/// }
+///
+/// # fn bad_condition() -> Option<i8> { None }
+/// ```
+#[macro_export]
+macro_rules! bail {
+ ($e:expr) => {
+ return Err($e.into());
+ };
+ ($fmt:expr, $($arg:tt)+) => {
+ return Err(format!($fmt, $($arg)+).into());
+ };
+}
+
+/// Exits a function early with an error if the condition is not satisfied
+///
+/// The `ensure!` macro is a convenience helper that provides a way to exit
+/// a function with an error if the given condition fails.
+///
+/// As an example, `ensure!(condition, "error code: {}", errcode)` is equivalent to
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let errcode = 0u8;
+/// # let condition = true;
+/// if !condition {
+/// bail!("error code: {}", errcode);
+/// }
+/// # Ok(())
+/// # }
+/// ```
+///
+/// See documentation for `bail!` macro for further details.
+#[macro_export(local_inner_macros)]
+macro_rules! ensure {
+ ($cond:expr, $e:expr) => {
+ if !($cond) {
+ bail!($e);
+ }
+ };
+ ($cond:expr, $fmt:expr, $($arg:tt)+) => {
+ if !($cond) {
+ bail!($fmt, $($arg)+);
+ }
+ };
+}
+
+#[doc(hidden)]
+pub mod mock {
+ error_chain! {}
+}