diff --git a/end.html b/end.html
index 1d5efbb..e4ff0e2 100644
--- a/end.html
+++ b/end.html
@@ -143,6 +143,8 @@
That's it for now…
Happy error handling!
+To report issues, submit pull request or for the source code, examples and the book source, visit
+the Git Repo.
diff --git a/print.html b/print.html
index 9d8a870..69b80dc 100644
--- a/print.html
+++ b/print.html
@@ -338,6 +338,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -1149,6 +1165,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -1961,6 +1993,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -2765,6 +2813,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -3584,6 +3648,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -4412,6 +4492,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -5237,6 +5333,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -6065,6 +6177,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -6902,6 +7030,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -7746,6 +7890,22 @@ fn main() -> Result<(), Box<Error>> {
#
# Along with the `ChainError<T>` struct, `chainerror` comes with some useful helper macros to save a lot of typing.
#
+# ## Features
+#
+# `no-fileline`
+# : completely turn off storing filename and line
+#
+# `display-cause`
+# : turn on printing a backtrace of the errors in `Display`
+#
+# `no-debug-cause`
+# : turn off printing a backtrace of the errors in `Debug`
+#
+#
+# # Tutorial
+#
+# Read the [Tutorial](https://haraldh.github.io/chainerror/tutorial1.html)
+#
# # Examples
#
# ~~~rust
@@ -8504,6 +8664,8 @@ fn main() -> Result<(), Box<Error>> {
That's it for now…
Happy error handling!
+To report issues, submit pull request or for the source code, examples and the book source, visit
+the Git Repo.
diff --git a/searchindex.js b/searchindex.js
index 06a7c56..0da24ab 100644
--- a/searchindex.js
+++ b/searchindex.js
@@ -1 +1 @@
-window.search = {"doc_urls":["index.html#chainerror","index.html#example","index.html#features","tutorial1.html#simple-string-errors","tutorial2.html#simple-chained-string-errors","tutorial2.html#what-did-we-do-here","tutorial3.html#mapping-errors","tutorial4.html#saving-coding-chars","tutorial5.html#the-source-of-errors","tutorial6.html#downcast-the-errors","tutorial7.html#the-root-cause-of-all-errors","tutorial8.html#finding-an-error-cause","tutorial9.html#selective-error-handling","tutorial10.html#errorkind-to-the-rescue","tutorial11.html#debug-for-the-errorkind","end.html#the-end"],"index":{"documentStore":{"docInfo":{"0":{"body":55,"breadcrumbs":1,"title":1},"1":{"body":170,"breadcrumbs":1,"title":1},"10":{"body":1358,"breadcrumbs":3,"title":3},"11":{"body":1325,"breadcrumbs":3,"title":3},"12":{"body":1339,"breadcrumbs":3,"title":3},"13":{"body":1393,"breadcrumbs":2,"title":2},"14":{"body":1382,"breadcrumbs":2,"title":2},"15":{"body":5,"breadcrumbs":1,"title":1},"2":{"body":20,"breadcrumbs":1,"title":1},"3":{"body":94,"breadcrumbs":3,"title":3},"4":{"body":1296,"breadcrumbs":4,"title":4},"5":{"body":44,"breadcrumbs":1,"title":1},"6":{"body":1314,"breadcrumbs":2,"title":2},"7":{"body":1300,"breadcrumbs":3,"title":3},"8":{"body":1313,"breadcrumbs":2,"title":2},"9":{"body":1323,"breadcrumbs":2,"title":2}},"docs":{"0":{"body":"chainerror provides an error backtrace like failure without doing a real backtrace, so even after you strip your binaries, you still have the error backtrace. chainerror has no dependencies! chainerror uses .source() of std::error::Error along with line()! and file()! to provide a nice debug error backtrace. It encapsulates all types, which have Display + Debug and can store the error cause internally. Along with the ChainError struct, chainerror comes with some useful helper macros to save a lot of typing. Debug information is worth it! Now continue reading the Tutorial","breadcrumbs":"chainerror","id":"0","title":"chainerror"},"1":{"body":"Output: $ cargo run -q --example example\nMain Error Report: func1 error calling func2 Error reported by Func2Error: func2 error: calling func3 The root cause was: std::io::Error: Kind( NotFound\n) Debug Error:\nexamples/example.rs:45: func1 error calling func2\nCaused by:\nexamples/example.rs:20: Func2Error(func2 error: calling func3)\nCaused by:\nexamples/example.rs:13: Error reading 'foo.txt'\nCaused by:\nKind(NotFound) use chainerror::*;\nuse std::error::Error;\nuse std::io;\nuse std::result::Result; fn do_some_io() -> Result<(), Box> { Err(io::Error::from(io::ErrorKind::NotFound))?; Ok(())\n} fn func3() -> Result<(), Box> { let filename = \"foo.txt\"; do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?; Ok(())\n} derive_str_cherr!(Func2Error); fn func2() -> ChainResult<(), Func2Error> { func3().map_err(mstrerr!(Func2Error, \"func2 error: calling func3\"))?; Ok(())\n} enum Func1Error { Func2, IO(String),\n} impl ::std::fmt::Display for Func1Error { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { match self { Func1Error::Func2 => write!(f, \"func1 error calling func2\"), Func1Error::IO(filename) => write!(f, \"Error reading '{}'\", filename), } }\n} impl ::std::fmt::Debug for Func1Error { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, \"{}\", self) }\n} fn func1() -> ChainResult<(), Func1Error> { func2().map_err(|e| cherr!(e, Func1Error::Func2))?; let filename = String::from(\"bar.txt\"); do_some_io().map_err(|e| cherr!(e, Func1Error::IO(filename)))?; Ok(())\n} fn main() { if let Err(e) = func1() { match e.kind() { Func1Error::Func2 => eprintln!(\"Main Error Report: func1 error calling func2\"), Func1Error::IO(filename) => { eprintln!(\"Main Error Report: func1 error reading '{}'\", filename) } } if let Some(e) = e.find_chain_cause::() { eprintln!(\"\\nError reported by Func2Error: {}\", e) } if let Some(e) = e.root_cause() { let ioerror = e.downcast_ref::().unwrap(); eprintln!(\"\\nThe root cause was: std::io::Error: {:#?}\", ioerror); } eprintln!(\"\\nDebug Error:\\n{:?}\", e); }\n}","breadcrumbs":"Example:","id":"1","title":"Example:"},"10":{"body":"chainerror also has some helper methods: fn is_chain(&self) -> bool\nfn downcast_chain_ref(&self) -> Option<&ChainError>\nfn downcast_chain_mut(&mut self) -> Option<&mut ChainError>\nfn root_cause(&self) -> Option<&(dyn Error + 'static)>\nfn find_cause(&self) -> Option<&U>\nfn find_chain_cause(&self) -> Option<&ChainError>\nfn kind<'a>(&'a self) -> &'a T Using downcast_chain_ref::() gives a ChainError , which can be used to call .find_cause::() . if let Some(s) = e.downcast_chain_ref::() { if let Some(ioerror) = s.find_cause::() { or to use .root_cause() , which of course can be of any type implementing std::error::Error . if let Some(e) = s.root_cause() { use crate::chainerror::*;\nuse std::error::Error;\nuse std::io;\nuse std::result::Result; fn do_some_io() -> Result<(), Box> { Err(io::Error::from(io::ErrorKind::NotFound))?; Ok(())\n} fn func2() -> Result<(), Box> { let filename = \"foo.txt\"; do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?; Ok(())\n} fn func1() -> Result<(), Box> { func2().map_err(mstrerr!(\"func1 error\"))?; Ok(())\n} fn main() -> Result<(), Box> { if let Err(e) = func1() { eprintln!(\"Error: {}\", e); if let Some(s) = e.downcast_chain_ref::() { if let Some(ioerror) = s.find_cause::() { eprintln!(\"caused by: std::io::Error: {}\", ioerror); match ioerror.kind() { io::ErrorKind::NotFound => eprintln!(\"of kind: std::io::ErrorKind::NotFound\"), _ => {} } } if let Some(e) = s.root_cause() { let ioerror = e.downcast_ref::().unwrap(); eprintln!(\"The root cause was: std::io::Error: {:#?}\", ioerror); } } } Ok(())\n}\n# #[allow(dead_code)]\n# mod chainerror {\n# /*!\n# # `chainerror` provides an error backtrace without doing a real backtrace, so even after you `strip` your\n# binaries, you still have the error backtrace.\n# # `chainerror` has no dependencies!\n# # `chainerror` uses `.source()` of `std::error::Error` along with `line()!` and `file()!` to provide a nice debug error backtrace.\n# It encapsulates all types, which have `Display + Debug` and can store the error cause internally.\n# # Along with the `ChainError` struct, `chainerror` comes with some useful helper macros to save a lot of typing.\n# # # Examples\n# # ~~~rust\n# use chainerror::*;\n# use std::error::Error;\n# use std::io;\n# use std::result::Result;\n# # fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(\"func1 error\"))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# assert_eq!(\n# format!(\"\\n{:?}\\n\", e), r#\"\n# src/lib.rs:20: func1 error\n# Caused by:\n# src/lib.rs:15: Error reading 'foo.txt'\n# Caused by:\n# Kind(NotFound)\n# \"#\n# );\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# # # ~~~rust\n# use chainerror::*;\n# use std::error::Error;\n# use std::io;\n# use std::result::Result;\n# # fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # fn func3() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func2Error);\n# # fn func2() -> ChainResult<(), Func2Error> {\n# func3().map_err(mstrerr!(Func2Error, \"func2 error: calling func3\"))?;\n# Ok(())\n# }\n# # enum Func1Error {\n# Func2,\n# IO(String),\n# }\n# # impl ::std::fmt::Display for Func1Error {\n# fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# match self {\n# Func1Error::Func2 => write!(f, \"func1 error calling func2\"),\n# Func1Error::IO(filename) => write!(f, \"Error reading '{}'\", filename),\n# }\n# }\n# }\n# # impl ::std::fmt::Debug for Func1Error {\n# fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# write!(f, \"{}\", self)\n# }\n# }\n# # fn func1() -> ChainResult<(), Func1Error> {\n# func2().map_err(|e| cherr!(e, Func1Error::Func2))?;\n# let filename = String::from(\"bar.txt\");\n# do_some_io().map_err(|e| cherr!(e, Func1Error::IO(filename)))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# assert!(\n# match e.kind() {\n# Func1Error::Func2 => {\n# eprintln!(\"Main Error Report: func1 error calling func2\");\n# true\n# }\n# Func1Error::IO(filename) => {\n# eprintln!(\"Main Error Report: func1 error reading '{}'\", filename);\n# false\n# }\n# }\n# );\n# # assert!(e.find_chain_cause::().is_some());\n# # if let Some(e) = e.find_chain_cause::() {\n# eprintln!(\"\\nError reported by Func2Error: {}\", e)\n# }\n# # # assert!(e.root_cause().is_some());\n# # if let Some(e) = e.root_cause() {\n# let ioerror = e.downcast_ref::().unwrap();\n# eprintln!(\"\\nThe root cause was: std::io::Error: {:#?}\", ioerror);\n# }\n# # assert_eq!(\n# format!(\"\\n{:?}\\n\", e), r#\"\n# src/lib.rs:47: func1 error calling func2\n# Caused by:\n# src/lib.rs:22: Func2Error(func2 error: calling func3)\n# Caused by:\n# src/lib.rs:15: Error reading 'foo.txt'\n# Caused by:\n# Kind(NotFound)\n# \"#\n# );\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# # !*/\n# # use std::any::TypeId;\n# use std::error::Error;\n# use std::fmt::{Debug, Display, Formatter, Result};\n# # /** chains an inner error kind `T` with a causing error\n# **/\n# pub struct ChainError {\n# #[cfg(not(feature = \"no-fileline\"))]\n# occurrence: Option<(u32, &'static str)>,\n# kind: T,\n# error_cause: Option>,\n# }\n# # /// convenience type alias\n# pub type ChainResult = std::result::Result>;\n# # impl ChainError {\n# #[cfg(not(feature = \"no-fileline\"))]\n# /// Use the `cherr!()` or `mstrerr!()` macro instead of calling this directly\n# pub fn new(\n# kind: T,\n# error_cause: Option>,\n# occurrence: Option<(u32, &'static str)>,\n# ) -> Self {\n# Self {\n# occurrence,\n# kind,\n# error_cause,\n# }\n# }\n# # #[cfg(feature = \"no-fileline\")]\n# /// Use the `cherr!()` or `mstrerr!()` macro instead of calling this directly\n# pub fn new(\n# kind: T,\n# error_cause: Option>,\n# _occurrence: Option<(u32, &'static str)>,\n# ) -> Self {\n# Self { kind, error_cause }\n# }\n# # /// return the root cause of the error chain, if any exists\n# pub fn root_cause(&self) -> Option<&(dyn Error + 'static)> {\n# let mut cause = self as &(dyn Error + 'static);\n# while let Some(c) = cause.source() {\n# cause = c;\n# }\n# Some(cause)\n# }\n# # /** find the first error cause of type U, if any exists\n# # # Examples\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func2Error);\n# # fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(Func2Error, \"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func1Error);\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(Func1Error, \"func1 error\"))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# if let Some(f1err) = e.downcast_chain_ref::() {\n# # assert!(f1err.find_cause::().is_some());\n# # assert!(f1err.find_chain_cause::().is_some());\n# }\n# # else {\n# # panic!();\n# # }\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# **/\n# pub fn find_cause(&self) -> Option<&U> {\n# let mut cause = self as &(dyn Error + 'static);\n# loop {\n# if cause.is::() {\n# return cause.downcast_ref::();\n# }\n# # match cause.source() {\n# Some(c) => cause = c,\n# None => return None,\n# }\n# }\n# }\n# # /** find the first error cause of type ChainError, if any exists\n# # Same as `find_cause`, but hides the `ChainError` implementation internals\n# # # Examples\n# # ~~~rust,ignore\n# /// Instead of writing\n# err.find_cause::>();\n# # /// leave out the ChainError implementation detail\n# err.find_chain_cause::();\n# ~~~\n# # **/\n# pub fn find_chain_cause(&self) -> Option<&ChainError> {\n# let mut cause = self as &(dyn Error + 'static);\n# loop {\n# if cause.is::>() {\n# return cause.downcast_ref::>();\n# }\n# # match cause.source() {\n# Some(c) => cause = c,\n# None => return None,\n# }\n# }\n# }\n# # /** return a reference to T of `ChainError`\n# # # Examples\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func2Error);\n# # fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(Func2Error, \"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # #[derive(Debug)]\n# enum Func1ErrorKind {\n# Func2,\n# IO(String),\n# }\n# # // impl ::std::fmt::Display for Func1ErrorKind {…}\n# # impl ::std::fmt::Display for Func1ErrorKind {\n# # fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# # match self {\n# # Func1ErrorKind::Func2 => write!(f, \"func1 error calling func2\"),\n# # Func1ErrorKind::IO(filename) => write!(f, \"Error reading '{}'\", filename),\n# # }\n# # }\n# # }\n# # fn func1() -> ChainResult<(), Func1ErrorKind> {\n# func2().map_err(|e| cherr!(e, Func1ErrorKind::Func2))?;\n# do_some_io().map_err(|e| cherr!(e, Func1ErrorKind::IO(\"bar.txt\".into())))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# match e.kind() {\n# Func1ErrorKind::Func2 => {},\n# Func1ErrorKind::IO(filename) => panic!(),\n# }\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# # **/\n# pub fn kind<'a>(&'a self) -> &'a T {\n# &self.kind\n# }\n# }\n# # /** convenience trait to hide the `ChainError` implementation internals\n# **/\n# pub trait ChainErrorDown {\n# /** test if of type `ChainError`\n# **/\n# fn is_chain(&self) -> bool;\n# /** downcast to a reference of `ChainError`\n# **/\n# fn downcast_chain_ref(&self) -> Option<&ChainError>;\n# /** downcast to a mutable reference of `ChainError`\n# **/\n# fn downcast_chain_mut(&mut self) -> Option<&mut ChainError>;\n# }\n# # impl ChainErrorDown for ChainError {\n# fn is_chain(&self) -> bool {\n# TypeId::of::() == TypeId::of::()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# if self.is_chain::() {\n# unsafe { Some(&*(self as *const dyn Error as *const &ChainError)) }\n# } else {\n# None\n# }\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# if self.is_chain::() {\n# unsafe { Some(&mut *(self as *mut dyn Error as *mut &mut ChainError)) }\n# } else {\n# None\n# }\n# }\n# }\n# # impl ChainErrorDown for dyn Error + 'static {\n# fn is_chain(&self) -> bool {\n# self.is::>()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# self.downcast_ref::>()\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# self.downcast_mut::>()\n# }\n# }\n# # impl ChainErrorDown for dyn Error + 'static + Send {\n# fn is_chain(&self) -> bool {\n# self.is::>()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# self.downcast_ref::>()\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# self.downcast_mut::>()\n# }\n# }\n# # impl ChainErrorDown for dyn Error + 'static + Send + Sync {\n# fn is_chain(&self) -> bool {\n# self.is::>()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# self.downcast_ref::>()\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# self.downcast_mut::>()\n# }\n# }\n# # impl Error for ChainError {\n# fn source(&self) -> Option<&(dyn Error + 'static)> {\n# if let Some(ref e) = self.error_cause {\n# Some(e.as_ref())\n# } else {\n# None\n# }\n# }\n# }\n# # impl Error for &ChainError {\n# fn source(&self) -> Option<&(dyn Error + 'static)> {\n# if let Some(ref e) = self.error_cause {\n# Some(e.as_ref())\n# } else {\n# None\n# }\n# }\n# }\n# # impl Error for &mut ChainError {\n# fn source(&self) -> Option<&(dyn Error + 'static)> {\n# if let Some(ref e) = self.error_cause {\n# Some(e.as_ref())\n# } else {\n# None\n# }\n# }\n# }\n# # impl Display for ChainError {\n# fn fmt(&self, f: &mut Formatter) -> Result {\n# write!(f, \"{}\", self.kind)?;\n# # #[cfg(feature = \"display-cause\")]\n# {\n# if let Some(e) = self.source() {\n# writeln!(f, \"\\nCaused by:\")?;\n# Display::fmt(&e, f)?;\n# }\n# }\n# Ok(())\n# }\n# }\n# # impl Debug for ChainError {\n# fn fmt(&self, f: &mut Formatter) -> Result {\n# #[cfg(not(feature = \"no-fileline\"))]\n# {\n# if let Some(o) = self.occurrence {\n# write!(f, \"{}:{}: \", o.1, o.0)?;\n# }\n# }\n# # if self.is_chain::() {\n# Display::fmt(&self.kind, f)?;\n# } else {\n# Debug::fmt(&self.kind, f)?;\n# }\n# # #[cfg(not(feature = \"no-debug-cause\"))]\n# {\n# if let Some(e) = self.source() {\n# writeln!(f, \"\\nCaused by:\")?;\n# Debug::fmt(&e, f)?;\n# }\n# }\n# Ok(())\n# }\n# }\n# # /** creates a new `ChainError`\n# # # Examples\n# # Create a new ChainError, where `FooError` must implement `Display` and `Debug`.\n# ~~~rust\n# # use chainerror::*;\n# #\n# # #[derive(Debug)]\n# enum FooError {\n# Bar,\n# Baz(&'static str),\n# }\n# #\n# # impl ::std::fmt::Display for FooError {\n# # fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# # match self {\n# # FooError::Bar => write!(f, \"Bar Error\"),\n# # FooError::Baz(s) => write!(f, \"Baz Error: '{}'\", s),\n# # }\n# # }\n# # }\n# # // impl ::std::fmt::Display for FooError\n# # fn do_some_stuff() -> bool {\n# false\n# }\n# # fn func() -> ChainResult<(), FooError> {\n# if ! do_some_stuff() {\n# Err(cherr!(FooError::Baz(\"Error\")))?;\n# }\n# Ok(())\n# }\n# #\n# # pub fn main() {\n# # match func().unwrap_err().kind() {\n# # FooError::Baz(s) if s == &\"Error\" => {},\n# # _ => panic!(),\n# # }\n# # }\n# ~~~\n# # Additionally an error cause can be added.\n# # ~~~rust\n# # use chainerror::*;\n# # use std::io;\n# # use std::error::Error;\n# #\n# # #[derive(Debug)]\n# # enum FooError {\n# # Bar,\n# # Baz(&'static str),\n# # }\n# #\n# # impl ::std::fmt::Display for FooError {\n# # fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# # match self {\n# # FooError::Bar => write!(f, \"Bar Error\"),\n# # FooError::Baz(s) => write!(f, \"Baz Error: '{}'\", s),\n# # }\n# # }\n# # }\n# #\n# fn do_some_stuff() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # fn func() -> ChainResult<(), FooError> {\n# do_some_stuff().map_err(\n# |e| cherr!(e, FooError::Baz(\"Error\"))\n# )?;\n# Ok(())\n# }\n# #\n# # pub fn main() {\n# # match func().unwrap_err().kind() {\n# # FooError::Baz(s) if s == &\"Error\" => {},\n# # _ => panic!(),\n# # }\n# # }\n# ~~~\n# # **/\n# #[macro_export]\n# macro_rules! cherr {\n# ( $k:expr ) => {\n# ChainError::<_>::new($k, None, Some((line!(), file!())))\n# };\n# ( $e:expr, $k:expr ) => {\n# ChainError::<_>::new($k, Some(Box::from($e)), Some((line!(), file!())))\n# };\n# }\n# # /** convenience macro for |e| cherr!(e, format!(…))\n# # # Examples\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# # fn do_some_io() -> Result<(), Box> {\n# # Err(io::Error::from(io::ErrorKind::NotFound))?;\n# # Ok(())\n# # }\n# #\n# fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(\"func1 error\"))?;\n# Ok(())\n# }\n# # # fn main() {\n# # if let Err(e) = func1() {\n# # assert_eq!(\n# # format!(\"\\n{:?}\\n\", e), r#\"\n# # src/lib.rs:20: func1 error\n# # Caused by:\n# # src/lib.rs:15: Error reading 'foo.txt'\n# # Caused by:\n# # Kind(NotFound)\n# # \"#\n# # );\n# # } else {\n# # unreachable!();\n# # }\n# # }\n# ~~~\n# # `mstrerr!()` can also be used to map a new `ChainError`, where T was defined with\n# `derive_str_cherr!(T)`\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# # fn do_some_io() -> Result<(), Box> {\n# # Err(io::Error::from(io::ErrorKind::NotFound))?;\n# # Ok(())\n# # }\n# #\n# derive_str_cherr!(Func2Error);\n# # fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(Func2Error, \"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func1Error);\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(Func1Error, \"func1 error\"))?;\n# Ok(())\n# }\n# #\n# # fn main() {\n# # if let Err(e) = func1() {\n# # if let Some(f1err) = e.downcast_chain_ref::() {\n# # assert!(f1err.find_cause::>().is_some());\n# # assert!(f1err.find_chain_cause::().is_some());\n# # } else {\n# # panic!();\n# # }\n# # } else {\n# # unreachable!();\n# # }\n# # }\n# ~~~\n# **/\n# #[macro_export]\n# macro_rules! mstrerr {\n# ( $t:ident, $v:expr $(, $more:expr)* ) => {\n# |e| cherr!(e, $t (format!($v, $( $more , )* )))\n# };\n# ( $t:path, $v:expr $(, $more:expr)* ) => {\n# |e| cherr!(e, $t (format!($v, $( $more , )* )))\n# };\n# ( $v:expr $(, $more:expr)* ) => {\n# |e| cherr!(e, format!($v, $( $more , )* ))\n# };\n# }\n# # /** convenience macro to create a \"new type\" T(String) and implement Display + Debug for T\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# # fn do_some_io() -> Result<(), Box> {\n# # Err(io::Error::from(io::ErrorKind::NotFound))?;\n# # Ok(())\n# # }\n# #\n# derive_str_cherr!(Func2Error);\n# # fn func2() -> ChainResult<(), Func2Error> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(Func2Error, \"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func1Error);\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(Func1Error, \"func1 error\"))?;\n# Ok(())\n# }\n# #\n# # fn main() {\n# # if let Err(e) = func1() {\n# # if let Some(f1err) = e.downcast_chain_ref::() {\n# # assert!(f1err.find_cause::>().is_some());\n# # assert!(f1err.find_chain_cause::().is_some());\n# # } else {\n# # panic!();\n# # }\n# # } else {\n# # unreachable!();\n# # }\n# # }\n# ~~~\n# # **/\n# #[macro_export]\n# macro_rules! derive_str_cherr {\n# ($e:ident) => {\n# struct $e(String);\n# impl ::std::fmt::Display for $e {\n# fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# write!(f, \"{}\", self.0)\n# }\n# }\n# impl ::std::fmt::Debug for $e {\n# fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# write!(f, \"{}({})\", stringify!($e), self.0)\n# }\n# }\n# impl ::std::error::Error for $e {}\n# };\n# }\n# }","breadcrumbs":"The root cause of all Errors","id":"10","title":"The root cause of all Errors"},"11":{"body":"To distinguish the errors occuring in various places, we can define named string errors with the \"new type\" pattern. derive_str_cherr!(Func2Error);\nderive_str_cherr!(Func1Error); Instead of ChainError we now have struct Func1Error(String) and ChainError . In the main function you can see, how we can match the different errors. Also see: if let Some(f2err) = f1err.find_chain_cause::() { as a shortcut to if let Some(f2err) = f1err.find_cause::>() { hiding the ChainError implementation detail. use crate::chainerror::*;\nuse std::error::Error;\nuse std::io;\nuse std::result::Result; fn do_some_io() -> Result<(), Box> { Err(io::Error::from(io::ErrorKind::NotFound))?; Ok(())\n} derive_str_cherr!(Func2Error); fn func2() -> Result<(), Box> { let filename = \"foo.txt\"; do_some_io().map_err(mstrerr!(Func2Error, \"Error reading '{}'\", filename))?; Ok(())\n} derive_str_cherr!(Func1Error); fn func1() -> Result<(), Box> { func2().map_err(mstrerr!(Func1Error, \"func1 error\"))?; Ok(())\n} fn main() -> Result<(), Box> { if let Err(e) = func1() { if let Some(f1err) = e.downcast_chain_ref::() { eprintln!(\"Func1Error: {}\", f1err); if let Some(f2err) = f1err.find_cause::>() { eprintln!(\"Func2Error: {}\", f2err); } if let Some(f2err) = f1err.find_chain_cause::() { eprintln!(\"Debug Func2Error:\\n{:?}\", f2err); } } } Ok(())\n}\n# #[allow(dead_code)]\n# mod chainerror {\n# /*!\n# # `chainerror` provides an error backtrace without doing a real backtrace, so even after you `strip` your\n# binaries, you still have the error backtrace.\n# # `chainerror` has no dependencies!\n# # `chainerror` uses `.source()` of `std::error::Error` along with `line()!` and `file()!` to provide a nice debug error backtrace.\n# It encapsulates all types, which have `Display + Debug` and can store the error cause internally.\n# # Along with the `ChainError` struct, `chainerror` comes with some useful helper macros to save a lot of typing.\n# # # Examples\n# # ~~~rust\n# use chainerror::*;\n# use std::error::Error;\n# use std::io;\n# use std::result::Result;\n# # fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(\"func1 error\"))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# assert_eq!(\n# format!(\"\\n{:?}\\n\", e), r#\"\n# src/lib.rs:20: func1 error\n# Caused by:\n# src/lib.rs:15: Error reading 'foo.txt'\n# Caused by:\n# Kind(NotFound)\n# \"#\n# );\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# # # ~~~rust\n# use chainerror::*;\n# use std::error::Error;\n# use std::io;\n# use std::result::Result;\n# # fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # fn func3() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func2Error);\n# # fn func2() -> ChainResult<(), Func2Error> {\n# func3().map_err(mstrerr!(Func2Error, \"func2 error: calling func3\"))?;\n# Ok(())\n# }\n# # enum Func1Error {\n# Func2,\n# IO(String),\n# }\n# # impl ::std::fmt::Display for Func1Error {\n# fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# match self {\n# Func1Error::Func2 => write!(f, \"func1 error calling func2\"),\n# Func1Error::IO(filename) => write!(f, \"Error reading '{}'\", filename),\n# }\n# }\n# }\n# # impl ::std::fmt::Debug for Func1Error {\n# fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# write!(f, \"{}\", self)\n# }\n# }\n# # fn func1() -> ChainResult<(), Func1Error> {\n# func2().map_err(|e| cherr!(e, Func1Error::Func2))?;\n# let filename = String::from(\"bar.txt\");\n# do_some_io().map_err(|e| cherr!(e, Func1Error::IO(filename)))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# assert!(\n# match e.kind() {\n# Func1Error::Func2 => {\n# eprintln!(\"Main Error Report: func1 error calling func2\");\n# true\n# }\n# Func1Error::IO(filename) => {\n# eprintln!(\"Main Error Report: func1 error reading '{}'\", filename);\n# false\n# }\n# }\n# );\n# # assert!(e.find_chain_cause::().is_some());\n# # if let Some(e) = e.find_chain_cause::() {\n# eprintln!(\"\\nError reported by Func2Error: {}\", e)\n# }\n# # # assert!(e.root_cause().is_some());\n# # if let Some(e) = e.root_cause() {\n# let ioerror = e.downcast_ref::().unwrap();\n# eprintln!(\"\\nThe root cause was: std::io::Error: {:#?}\", ioerror);\n# }\n# # assert_eq!(\n# format!(\"\\n{:?}\\n\", e), r#\"\n# src/lib.rs:47: func1 error calling func2\n# Caused by:\n# src/lib.rs:22: Func2Error(func2 error: calling func3)\n# Caused by:\n# src/lib.rs:15: Error reading 'foo.txt'\n# Caused by:\n# Kind(NotFound)\n# \"#\n# );\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# # !*/\n# # use std::any::TypeId;\n# use std::error::Error;\n# use std::fmt::{Debug, Display, Formatter, Result};\n# # /** chains an inner error kind `T` with a causing error\n# **/\n# pub struct ChainError {\n# #[cfg(not(feature = \"no-fileline\"))]\n# occurrence: Option<(u32, &'static str)>,\n# kind: T,\n# error_cause: Option>,\n# }\n# # /// convenience type alias\n# pub type ChainResult = std::result::Result>;\n# # impl ChainError {\n# #[cfg(not(feature = \"no-fileline\"))]\n# /// Use the `cherr!()` or `mstrerr!()` macro instead of calling this directly\n# pub fn new(\n# kind: T,\n# error_cause: Option>,\n# occurrence: Option<(u32, &'static str)>,\n# ) -> Self {\n# Self {\n# occurrence,\n# kind,\n# error_cause,\n# }\n# }\n# # #[cfg(feature = \"no-fileline\")]\n# /// Use the `cherr!()` or `mstrerr!()` macro instead of calling this directly\n# pub fn new(\n# kind: T,\n# error_cause: Option>,\n# _occurrence: Option<(u32, &'static str)>,\n# ) -> Self {\n# Self { kind, error_cause }\n# }\n# # /// return the root cause of the error chain, if any exists\n# pub fn root_cause(&self) -> Option<&(dyn Error + 'static)> {\n# let mut cause = self as &(dyn Error + 'static);\n# while let Some(c) = cause.source() {\n# cause = c;\n# }\n# Some(cause)\n# }\n# # /** find the first error cause of type U, if any exists\n# # # Examples\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func2Error);\n# # fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(Func2Error, \"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func1Error);\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(Func1Error, \"func1 error\"))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# if let Some(f1err) = e.downcast_chain_ref::() {\n# # assert!(f1err.find_cause::().is_some());\n# # assert!(f1err.find_chain_cause::().is_some());\n# }\n# # else {\n# # panic!();\n# # }\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# **/\n# pub fn find_cause(&self) -> Option<&U> {\n# let mut cause = self as &(dyn Error + 'static);\n# loop {\n# if cause.is::() {\n# return cause.downcast_ref::();\n# }\n# # match cause.source() {\n# Some(c) => cause = c,\n# None => return None,\n# }\n# }\n# }\n# # /** find the first error cause of type ChainError, if any exists\n# # Same as `find_cause`, but hides the `ChainError` implementation internals\n# # # Examples\n# # ~~~rust,ignore\n# /// Instead of writing\n# err.find_cause::>();\n# # /// leave out the ChainError implementation detail\n# err.find_chain_cause::();\n# ~~~\n# # **/\n# pub fn find_chain_cause(&self) -> Option<&ChainError> {\n# let mut cause = self as &(dyn Error + 'static);\n# loop {\n# if cause.is::>() {\n# return cause.downcast_ref::>();\n# }\n# # match cause.source() {\n# Some(c) => cause = c,\n# None => return None,\n# }\n# }\n# }\n# # /** return a reference to T of `ChainError`\n# # # Examples\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# fn do_some_io() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # derive_str_cherr!(Func2Error);\n# # fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(Func2Error, \"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # #[derive(Debug)]\n# enum Func1ErrorKind {\n# Func2,\n# IO(String),\n# }\n# # // impl ::std::fmt::Display for Func1ErrorKind {…}\n# # impl ::std::fmt::Display for Func1ErrorKind {\n# # fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# # match self {\n# # Func1ErrorKind::Func2 => write!(f, \"func1 error calling func2\"),\n# # Func1ErrorKind::IO(filename) => write!(f, \"Error reading '{}'\", filename),\n# # }\n# # }\n# # }\n# # fn func1() -> ChainResult<(), Func1ErrorKind> {\n# func2().map_err(|e| cherr!(e, Func1ErrorKind::Func2))?;\n# do_some_io().map_err(|e| cherr!(e, Func1ErrorKind::IO(\"bar.txt\".into())))?;\n# Ok(())\n# }\n# # fn main() {\n# if let Err(e) = func1() {\n# match e.kind() {\n# Func1ErrorKind::Func2 => {},\n# Func1ErrorKind::IO(filename) => panic!(),\n# }\n# }\n# # else {\n# # unreachable!();\n# # }\n# }\n# ~~~\n# # **/\n# pub fn kind<'a>(&'a self) -> &'a T {\n# &self.kind\n# }\n# }\n# # /** convenience trait to hide the `ChainError` implementation internals\n# **/\n# pub trait ChainErrorDown {\n# /** test if of type `ChainError`\n# **/\n# fn is_chain(&self) -> bool;\n# /** downcast to a reference of `ChainError`\n# **/\n# fn downcast_chain_ref(&self) -> Option<&ChainError>;\n# /** downcast to a mutable reference of `ChainError`\n# **/\n# fn downcast_chain_mut(&mut self) -> Option<&mut ChainError>;\n# }\n# # impl ChainErrorDown for ChainError {\n# fn is_chain(&self) -> bool {\n# TypeId::of::() == TypeId::of::()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# if self.is_chain::() {\n# unsafe { Some(&*(self as *const dyn Error as *const &ChainError)) }\n# } else {\n# None\n# }\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# if self.is_chain::() {\n# unsafe { Some(&mut *(self as *mut dyn Error as *mut &mut ChainError)) }\n# } else {\n# None\n# }\n# }\n# }\n# # impl ChainErrorDown for dyn Error + 'static {\n# fn is_chain(&self) -> bool {\n# self.is::>()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# self.downcast_ref::>()\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# self.downcast_mut::>()\n# }\n# }\n# # impl ChainErrorDown for dyn Error + 'static + Send {\n# fn is_chain(&self) -> bool {\n# self.is::>()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# self.downcast_ref::>()\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# self.downcast_mut::>()\n# }\n# }\n# # impl ChainErrorDown for dyn Error + 'static + Send + Sync {\n# fn is_chain(&self) -> bool {\n# self.is::>()\n# }\n# # fn downcast_chain_ref(&self) -> Option<&ChainError> {\n# self.downcast_ref::>()\n# }\n# # fn downcast_chain_mut(&mut self) -> Option<&mut ChainError> {\n# self.downcast_mut::>()\n# }\n# }\n# # impl Error for ChainError {\n# fn source(&self) -> Option<&(dyn Error + 'static)> {\n# if let Some(ref e) = self.error_cause {\n# Some(e.as_ref())\n# } else {\n# None\n# }\n# }\n# }\n# # impl Error for &ChainError {\n# fn source(&self) -> Option<&(dyn Error + 'static)> {\n# if let Some(ref e) = self.error_cause {\n# Some(e.as_ref())\n# } else {\n# None\n# }\n# }\n# }\n# # impl Error for &mut ChainError {\n# fn source(&self) -> Option<&(dyn Error + 'static)> {\n# if let Some(ref e) = self.error_cause {\n# Some(e.as_ref())\n# } else {\n# None\n# }\n# }\n# }\n# # impl Display for ChainError {\n# fn fmt(&self, f: &mut Formatter) -> Result {\n# write!(f, \"{}\", self.kind)?;\n# # #[cfg(feature = \"display-cause\")]\n# {\n# if let Some(e) = self.source() {\n# writeln!(f, \"\\nCaused by:\")?;\n# Display::fmt(&e, f)?;\n# }\n# }\n# Ok(())\n# }\n# }\n# # impl Debug for ChainError {\n# fn fmt(&self, f: &mut Formatter) -> Result {\n# #[cfg(not(feature = \"no-fileline\"))]\n# {\n# if let Some(o) = self.occurrence {\n# write!(f, \"{}:{}: \", o.1, o.0)?;\n# }\n# }\n# # if self.is_chain::() {\n# Display::fmt(&self.kind, f)?;\n# } else {\n# Debug::fmt(&self.kind, f)?;\n# }\n# # #[cfg(not(feature = \"no-debug-cause\"))]\n# {\n# if let Some(e) = self.source() {\n# writeln!(f, \"\\nCaused by:\")?;\n# Debug::fmt(&e, f)?;\n# }\n# }\n# Ok(())\n# }\n# }\n# # /** creates a new `ChainError`\n# # # Examples\n# # Create a new ChainError, where `FooError` must implement `Display` and `Debug`.\n# ~~~rust\n# # use chainerror::*;\n# #\n# # #[derive(Debug)]\n# enum FooError {\n# Bar,\n# Baz(&'static str),\n# }\n# #\n# # impl ::std::fmt::Display for FooError {\n# # fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# # match self {\n# # FooError::Bar => write!(f, \"Bar Error\"),\n# # FooError::Baz(s) => write!(f, \"Baz Error: '{}'\", s),\n# # }\n# # }\n# # }\n# # // impl ::std::fmt::Display for FooError\n# # fn do_some_stuff() -> bool {\n# false\n# }\n# # fn func() -> ChainResult<(), FooError> {\n# if ! do_some_stuff() {\n# Err(cherr!(FooError::Baz(\"Error\")))?;\n# }\n# Ok(())\n# }\n# #\n# # pub fn main() {\n# # match func().unwrap_err().kind() {\n# # FooError::Baz(s) if s == &\"Error\" => {},\n# # _ => panic!(),\n# # }\n# # }\n# ~~~\n# # Additionally an error cause can be added.\n# # ~~~rust\n# # use chainerror::*;\n# # use std::io;\n# # use std::error::Error;\n# #\n# # #[derive(Debug)]\n# # enum FooError {\n# # Bar,\n# # Baz(&'static str),\n# # }\n# #\n# # impl ::std::fmt::Display for FooError {\n# # fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n# # match self {\n# # FooError::Bar => write!(f, \"Bar Error\"),\n# # FooError::Baz(s) => write!(f, \"Baz Error: '{}'\", s),\n# # }\n# # }\n# # }\n# #\n# fn do_some_stuff() -> Result<(), Box> {\n# Err(io::Error::from(io::ErrorKind::NotFound))?;\n# Ok(())\n# }\n# # fn func() -> ChainResult<(), FooError> {\n# do_some_stuff().map_err(\n# |e| cherr!(e, FooError::Baz(\"Error\"))\n# )?;\n# Ok(())\n# }\n# #\n# # pub fn main() {\n# # match func().unwrap_err().kind() {\n# # FooError::Baz(s) if s == &\"Error\" => {},\n# # _ => panic!(),\n# # }\n# # }\n# ~~~\n# # **/\n# #[macro_export]\n# macro_rules! cherr {\n# ( $k:expr ) => {\n# ChainError::<_>::new($k, None, Some((line!(), file!())))\n# };\n# ( $e:expr, $k:expr ) => {\n# ChainError::<_>::new($k, Some(Box::from($e)), Some((line!(), file!())))\n# };\n# }\n# # /** convenience macro for |e| cherr!(e, format!(…))\n# # # Examples\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# # fn do_some_io() -> Result<(), Box> {\n# # Err(io::Error::from(io::ErrorKind::NotFound))?;\n# # Ok(())\n# # }\n# #\n# fn func2() -> Result<(), Box> {\n# let filename = \"foo.txt\";\n# do_some_io().map_err(mstrerr!(\"Error reading '{}'\", filename))?;\n# Ok(())\n# }\n# # fn func1() -> Result<(), Box> {\n# func2().map_err(mstrerr!(\"func1 error\"))?;\n# Ok(())\n# }\n# # # fn main() {\n# # if let Err(e) = func1() {\n# # assert_eq!(\n# # format!(\"\\n{:?}\\n\", e), r#\"\n# # src/lib.rs:20: func1 error\n# # Caused by:\n# # src/lib.rs:15: Error reading 'foo.txt'\n# # Caused by:\n# # Kind(NotFound)\n# # \"#\n# # );\n# # } else {\n# # unreachable!();\n# # }\n# # }\n# ~~~\n# # `mstrerr!()` can also be used to map a new `ChainError`, where T was defined with\n# `derive_str_cherr!(T)`\n# # ~~~rust\n# # use crate::chainerror::*;\n# # use std::error::Error;\n# # use std::io;\n# # use std::result::Result;\n# #\n# # fn do_some_io() -> Result<(), Box> {\n# # Err(io::Error::from(io::ErrorKind::NotFound))?;\n# # Ok(())\n# # }\n# #\n# derive_str_cherr!(Func2Error);\n# # fn func2() -> Result<(), Box