diff --git a/booksrc/tutorial12.md b/booksrc/tutorial12.md index 682eaa8..6373ca0 100644 --- a/booksrc/tutorial12.md +++ b/booksrc/tutorial12.md @@ -1,7 +1,7 @@ # Deref for the ErrorKind -Because ChainError implements Deref to &T, we can also match on `*e` instead of `e.kind()`. - +Because ChainError implements Deref to &T, we can also match on `*e` instead of `e.kind()` +or call a function with `&e` ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial12.rs:2:}} diff --git a/examples/tutorial12.rs b/examples/tutorial12.rs index 38ff09e..a20fede 100644 --- a/examples/tutorial12.rs +++ b/examples/tutorial12.rs @@ -45,6 +45,15 @@ fn func1() -> ChainResult<(), Func1ErrorKind> { Ok(()) } +fn handle_func1errorkind(e: &Func1ErrorKind) { + match e { + Func1ErrorKind::Func2 => eprintln!("Main Error Report: func1 error calling func2"), + Func1ErrorKind::IO(ref filename) => { + eprintln!("Main Error Report: func1 error reading '{}'", filename) + } + } +} + fn main() -> Result<(), Box> { if let Err(e) = func1() { match *e { @@ -54,6 +63,8 @@ fn main() -> Result<(), Box> { } } + handle_func1errorkind(&e); + if let Some(e) = e.find_chain_cause::() { eprintln!("\nError reported by Func2Error: {}", e) } diff --git a/src/lib.rs b/src/lib.rs index ca9d75e..b71e51d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -263,7 +263,7 @@ impl ChainError { self.iter().filter_map(Error::downcast_ref::).next() } - /// Find the first error cause of type ChainError, if any exists + /// Find the first error cause of type `ChainError`, if any exists /// /// Same as `find_cause`, but hides the `ChainError` implementation internals /// @@ -273,7 +273,7 @@ impl ChainError { /// // Instead of writing /// err.find_cause::>(); /// - /// // leave out the ChainError implementation detail + /// // leave out the ChainError implementation detail /// err.find_chain_cause::(); /// ~~~ pub fn find_chain_cause(&self) -> Option<&ChainError> { @@ -282,8 +282,24 @@ impl ChainError { .next() } - // FIXME: naming - fn find_chain_or_cause(&self) -> Option<&U> { + /// Find the first error cause of type `ChainError` or `U`, if any exists and return `U` + /// + /// Same as `find_cause` and `find_chain_cause`, but hides the `ChainError` implementation internals + /// + /// # Examples + /// + /// ~~~rust,ignore + /// // Instead of writing + /// err.find_cause::>(); + /// // and/or + /// err.find_chain_cause::(); + /// // and/or + /// err.find_cause::(); + /// + /// // leave out the ChainError implementation detail + /// err.find_chain_or_kind::(); + /// ~~~ + pub fn find_kind_or_cause(&self) -> Option<&U> { self.iter() .filter_map(|e| { e.downcast_ref::>().map(|e| e.kind()) @@ -353,6 +369,11 @@ impl ChainError { &self.kind } + /// Returns an Iterator over all error causes/sources + /// + /// # Example + /// + /// pub fn iter(&self) -> impl Iterator { ErrorIter { current: Some(self), @@ -378,7 +399,7 @@ impl std::ops::Deref for ChainError { type Target = T; fn deref(&self) -> &Self::Target { - self.kind() + &self.kind } }