mirror of
https://github.com/haraldh/chainerror.git
synced 2025-01-31 00:56:41 +01:00
deref
This commit is contained in:
parent
4762a75cfe
commit
c9259a3ea3
|
@ -1,7 +1,7 @@
|
||||||
# Deref for the ErrorKind
|
# Deref for the ErrorKind
|
||||||
|
|
||||||
Because ChainError<T> implements Deref to &T, we can also match on `*e` instead of `e.kind()`.
|
Because ChainError<T> implements Deref to &T, we can also match on `*e` instead of `e.kind()`
|
||||||
|
or call a function with `&e`
|
||||||
~~~rust
|
~~~rust
|
||||||
use crate::chainerror::*;
|
use crate::chainerror::*;
|
||||||
{{#include ../examples/tutorial12.rs:2:}}
|
{{#include ../examples/tutorial12.rs:2:}}
|
||||||
|
|
|
@ -45,6 +45,15 @@ fn func1() -> ChainResult<(), Func1ErrorKind> {
|
||||||
Ok(())
|
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<Error>> {
|
fn main() -> Result<(), Box<Error>> {
|
||||||
if let Err(e) = func1() {
|
if let Err(e) = func1() {
|
||||||
match *e {
|
match *e {
|
||||||
|
@ -54,6 +63,8 @@ fn main() -> Result<(), Box<Error>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_func1errorkind(&e);
|
||||||
|
|
||||||
if let Some(e) = e.find_chain_cause::<Func2Error>() {
|
if let Some(e) = e.find_chain_cause::<Func2Error>() {
|
||||||
eprintln!("\nError reported by Func2Error: {}", e)
|
eprintln!("\nError reported by Func2Error: {}", e)
|
||||||
}
|
}
|
||||||
|
|
31
src/lib.rs
31
src/lib.rs
|
@ -263,7 +263,7 @@ impl<T: 'static + Display + Debug> ChainError<T> {
|
||||||
self.iter().filter_map(Error::downcast_ref::<U>).next()
|
self.iter().filter_map(Error::downcast_ref::<U>).next()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the first error cause of type ChainError<U>, if any exists
|
/// Find the first error cause of type `ChainError<U>`, if any exists
|
||||||
///
|
///
|
||||||
/// Same as `find_cause`, but hides the `ChainError<U>` implementation internals
|
/// Same as `find_cause`, but hides the `ChainError<U>` implementation internals
|
||||||
///
|
///
|
||||||
|
@ -273,7 +273,7 @@ impl<T: 'static + Display + Debug> ChainError<T> {
|
||||||
/// // Instead of writing
|
/// // Instead of writing
|
||||||
/// err.find_cause::<ChainError<FooError>>();
|
/// err.find_cause::<ChainError<FooError>>();
|
||||||
///
|
///
|
||||||
/// // leave out the ChainError<T> implementation detail
|
/// // leave out the ChainError<FooError> implementation detail
|
||||||
/// err.find_chain_cause::<FooError>();
|
/// err.find_chain_cause::<FooError>();
|
||||||
/// ~~~
|
/// ~~~
|
||||||
pub fn find_chain_cause<U: Error + 'static>(&self) -> Option<&ChainError<U>> {
|
pub fn find_chain_cause<U: Error + 'static>(&self) -> Option<&ChainError<U>> {
|
||||||
|
@ -282,8 +282,24 @@ impl<T: 'static + Display + Debug> ChainError<T> {
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: naming
|
/// Find the first error cause of type `ChainError<U>` or `U`, if any exists and return `U`
|
||||||
fn find_chain_or_cause<U: Error + 'static>(&self) -> Option<&U> {
|
///
|
||||||
|
/// Same as `find_cause` and `find_chain_cause`, but hides the `ChainError<U>` implementation internals
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ~~~rust,ignore
|
||||||
|
/// // Instead of writing
|
||||||
|
/// err.find_cause::<ChainError<FooErrorKind>>();
|
||||||
|
/// // and/or
|
||||||
|
/// err.find_chain_cause::<FooErrorKind>();
|
||||||
|
/// // and/or
|
||||||
|
/// err.find_cause::<FooErrorKind>();
|
||||||
|
///
|
||||||
|
/// // leave out the ChainError<FooErrorKind> implementation detail
|
||||||
|
/// err.find_chain_or_kind::<FooErrorKind>();
|
||||||
|
/// ~~~
|
||||||
|
pub fn find_kind_or_cause<U: Error + 'static>(&self) -> Option<&U> {
|
||||||
self.iter()
|
self.iter()
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
e.downcast_ref::<ChainError<U>>().map(|e| e.kind())
|
e.downcast_ref::<ChainError<U>>().map(|e| e.kind())
|
||||||
|
@ -353,6 +369,11 @@ impl<T: 'static + Display + Debug> ChainError<T> {
|
||||||
&self.kind
|
&self.kind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an Iterator over all error causes/sources
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
///
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &(dyn Error + 'static)> {
|
pub fn iter(&self) -> impl Iterator<Item = &(dyn Error + 'static)> {
|
||||||
ErrorIter {
|
ErrorIter {
|
||||||
current: Some(self),
|
current: Some(self),
|
||||||
|
@ -378,7 +399,7 @@ impl<T: 'static + Display + Debug> std::ops::Deref for ChainError<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
self.kind()
|
&self.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue