From c2f674cc298c5da0aea809191f6471a4f12246a7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 30 Oct 2018 18:40:50 +0100 Subject: [PATCH] libimagerror: Move from error-chain to failure Signed-off-by: Matthias Beyer --- lib/core/libimagerror/Cargo.toml | 7 +- lib/core/libimagerror/src/iter.rs | 110 ++++++++--------------------- lib/core/libimagerror/src/lib.rs | 8 ++- lib/core/libimagerror/src/trace.rs | 30 ++++---- 4 files changed, 53 insertions(+), 102 deletions(-) diff --git a/lib/core/libimagerror/Cargo.toml b/lib/core/libimagerror/Cargo.toml index 914bf598..3b2aa969 100644 --- a/lib/core/libimagerror/Cargo.toml +++ b/lib/core/libimagerror/Cargo.toml @@ -20,6 +20,7 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } maintenance = { status = "actively-developed" } [dependencies] -log = "0.4" -ansi_term = "0.11" -error-chain = "0.12" +log = "0.4" +ansi_term = "0.11" +failure = "0.1" +failure_derive = "0.1" diff --git a/lib/core/libimagerror/src/iter.rs b/lib/core/libimagerror/src/iter.rs index 2bca4649..db7de991 100644 --- a/lib/core/libimagerror/src/iter.rs +++ b/lib/core/libimagerror/src/iter.rs @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error_chain::ChainedError; +use failure::Error; /// An iterator that unwraps the `Ok` items of `iter`, while passing the `Err` items to its /// closure `f`. @@ -31,9 +31,10 @@ pub struct UnwrapWith{ f: F } -impl Iterator for UnwrapWith where - I: Iterator>, - F: FnMut(E) +impl Iterator for UnwrapWith + where + I: Iterator>, + F: FnMut(Error) { type Item = T; @@ -41,14 +42,13 @@ impl Iterator for UnwrapWith where fn next(&mut self) -> Option { loop { match self.iter.next() { - Some(Err(e)) => { - (self.f)(e); - }, + Some(Err(e)) => { (self.f)(e); }, Some(Ok(item)) => return Some(item), - None => return None, + None => return None, } } } + #[inline] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); @@ -56,32 +56,14 @@ impl Iterator for UnwrapWith where } } -impl DoubleEndedIterator for UnwrapWith where - I: DoubleEndedIterator>, - F: FnMut(E) -{ - #[inline] - fn next_back(&mut self) -> Option { - loop { - match self.iter.next_back() { - Some(Err(e)) => { - (self.f)(e); - }, - Some(Ok(item)) => return Some(item), - None => return None, - } - } - } -} + /// Iterator helper for Unwrap with exiting on error -pub struct UnwrapExit(I, i32) - where I: Iterator>, - E: ChainedError; +pub struct UnwrapExit(I, i32) + where I: Iterator>; -impl Iterator for UnwrapExit - where I: Iterator>, - E: ChainedError +impl Iterator for UnwrapExit + where I: Iterator>, { type Item = T; @@ -91,9 +73,8 @@ impl Iterator for UnwrapExit } } -impl DoubleEndedIterator for UnwrapExit - where I: DoubleEndedIterator>, - E: ChainedError +impl DoubleEndedIterator for UnwrapExit + where I: DoubleEndedIterator>, { fn next_back(&mut self) -> Option { use trace::MapErrTrace; @@ -102,18 +83,21 @@ impl DoubleEndedIterator for UnwrapExit } /// This trait provides methods that make it easier to work with iterators that yield a `Result`. -pub trait TraceIterator : Iterator> + Sized { - /// Creates an iterator that yields the item in each `Ok` item, while filtering out the `Err` +pub trait TraceIterator : Iterator> + Sized { + /// Creates an iterator that yields the item in each `Ok` item, while filtering out the + /// `Err` /// items. Each filtered `Err` will be trace-logged with [`::trace::trace_error`]. /// /// As with all iterators, the processing is lazy. If you do not use the result of this method, /// nothing will be passed to `::trace::trace_error`, no matter how many `Err` items might /// be present. #[inline] - fn trace_unwrap(self) -> UnwrapWith where E: ChainedError { + fn trace_unwrap(self) -> UnwrapWith { #[inline] - fn trace_error>(err: E) { - eprintln!("{}", err.display_chain()); + fn trace_error(err: Error) { + err.iter_chain().for_each(|cause| { + eprintln!("{}", cause); + }); } self.unwrap_with(trace_error) @@ -127,12 +111,11 @@ pub trait TraceIterator : Iterator> + Sized { /// nothing will be passed to `::trace::trace_error_exit`, no matter how many `Err` items might /// be present. #[inline] - fn trace_unwrap_exit(self, exitcode: i32) -> UnwrapExit - where E: ChainedError - { + fn trace_unwrap_exit(self, exitcode: i32) -> UnwrapExit { UnwrapExit(self, exitcode) } + /// Takes a closure and creates an iterator that will yield the items inside all `Ok` items /// yielded by the original iterator. All `Err` items will be filtered out, and the contents /// of each `Err` will be passed to the closure. @@ -141,50 +124,13 @@ pub trait TraceIterator : Iterator> + Sized { /// for the closure to be called. #[inline] fn unwrap_with(self, f: F) -> UnwrapWith - where F: FnMut(E) + where F: FnMut(Error) { UnwrapWith { iter: self, f } } } -impl TraceIterator for I where - I: Iterator> +impl TraceIterator for I where + I: Iterator> {} -#[cfg(test)] -mod test { - use super::TraceIterator; - - #[derive(Copy, Clone, Eq, PartialEq, Debug)] - struct TestError(i32); - - #[test] - fn test_unwrap_with() { - let original = vec![Ok(1), Err(TestError(2)), Ok(3), Err(TestError(4))]; - let mut errs = vec![]; - - let oks = original - .into_iter() - .unwrap_with(|e|errs.push(e)) - .collect::>(); - - assert_eq!(&oks, &[1, 3]); - assert_eq!(&errs, &[TestError(2), TestError(4)]); - } - - #[test] - fn test_unwrap_with_backward() { - let original = vec![Ok(1), Err(TestError(2)), Ok(3), Err(TestError(4))]; - let mut errs = vec![]; - - let oks = original - .into_iter() - .rev() - .unwrap_with(|e|errs.push(e)) - .collect::>(); - - assert_eq!(&oks, &[3, 1]); - assert_eq!(&errs, &[TestError(4), TestError(2)]); - } - -} diff --git a/lib/core/libimagerror/src/lib.rs b/lib/core/libimagerror/src/lib.rs index a17aa21e..fba36561 100644 --- a/lib/core/libimagerror/src/lib.rs +++ b/lib/core/libimagerror/src/lib.rs @@ -35,11 +35,13 @@ #[macro_use] extern crate log; extern crate ansi_term; -extern crate error_chain; +extern crate failure; +#[macro_use] extern crate failure_derive; -pub mod io; +pub mod errors; pub mod exit; -pub mod trace; +pub mod io; pub mod iter; pub mod str; +pub mod trace; diff --git a/lib/core/libimagerror/src/trace.rs b/lib/core/libimagerror/src/trace.rs index 160fe340..cc184994 100644 --- a/lib/core/libimagerror/src/trace.rs +++ b/lib/core/libimagerror/src/trace.rs @@ -21,7 +21,7 @@ use std::process::exit; use std::fmt::Display; use std::fmt::Formatter; use std::fmt::Result as FmtResult; -use error_chain::ChainedError; +use failure::Error; use ansi_term::Colour::Red; struct ImagTrace<'a, T: 'a + ?Sized>(&'a T); @@ -32,32 +32,34 @@ impl<'a, T: 'a + ?Sized> ImagTrace<'a, T> { } } -impl<'a, T> Display for ImagTrace<'a, T> - where T: ChainedError +impl<'a> Display for ImagTrace<'a, Error> { fn fmt(&self, fmt: &mut Formatter) -> FmtResult { - try!(writeln!(fmt, "{}: {}", Red.blink().paint("ERROR[ 0]"), self.0)); + let _ = writeln!(fmt, "{}: {}", Red.blink().paint("ERROR[ 0]"), self.0)?; - for (i, e) in self.0.iter().enumerate().skip(1) { - try!(writeln!(fmt, "{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", i)), e)); + { + for (i, cause) in self.0.iter_causes().enumerate() { + let _ = writeln!(fmt, + "{prefix}: {error}", + prefix = Red.blink().paint(format!("ERROR[{:>4}]", i)), + error = cause)?; + } } - if let Some(backtrace) = self.0.backtrace() { - try!(writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))); - try!(writeln!(fmt, "{:?}", backtrace)); - } + let _ = writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))?; + let _ = writeln!(fmt, "{:?}", self.0.backtrace())?; Ok(()) } } -pub fn trace_error>(e: &C) { +pub fn trace_error(e: &Error) { eprintln!("{}", ImagTrace::new(e)); } -pub fn trace_error_dbg>(e: &C) { - debug!("{}", e.display_chain()); +pub fn trace_error_dbg(e: &Error) { + debug!("{}", ImagTrace::new(e)); } /// Helper functions for `Result` types to reduce overhead in the following situations: @@ -74,7 +76,7 @@ pub trait MapErrTrace { fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output; } -impl> MapErrTrace for Result { +impl MapErrTrace for Result { type Output = U; /// Simply call `trace_error()` on the Err (if there is one) and return the error.