diff --git a/libimagentrylist/Cargo.toml b/libimagentrylist/Cargo.toml index d254bf0d..97c099c9 100644 --- a/libimagentrylist/Cargo.toml +++ b/libimagentrylist/Cargo.toml @@ -14,3 +14,6 @@ path = "../libimagstore" [dependencies.libimagerror] path = "../libimagerror" +[dependencies.libimagutil] +path = "../libimagutil" + diff --git a/libimagentrylist/src/lib.rs b/libimagentrylist/src/lib.rs index 082b6fa3..14bf910c 100644 --- a/libimagentrylist/src/lib.rs +++ b/libimagentrylist/src/lib.rs @@ -19,6 +19,7 @@ extern crate clap; extern crate toml; extern crate libimagstore; +extern crate libimagutil; #[macro_use] extern crate libimagerror; pub mod cli; diff --git a/libimagentrylist/src/listers/line.rs b/libimagentrylist/src/listers/line.rs index 1b233dc0..241e39d8 100644 --- a/libimagentrylist/src/listers/line.rs +++ b/libimagentrylist/src/listers/line.rs @@ -5,6 +5,7 @@ use lister::Lister; use result::Result; use libimagstore::store::FileLockEntry; +use libimagutil::iter::fold_ok; pub struct LineLister<'a> { unknown_output: &'a str, @@ -26,13 +27,10 @@ impl<'a> Lister for LineLister<'a> { use error::ListError as LE; use error::ListErrorKind as LEK; - entries.fold(Ok(()), |accu, entry| { - accu.and_then(|_| { - write!(stdout(), "{:?}\n", - entry.get_location().to_str().unwrap_or(self.unknown_output)) - .map_err(|e| LE::new(LEK::FormatError, Some(Box::new(e)))) - }) - }) + fold_ok(entries, |entry| { + write!(stdout(), "{:?}\n", entry.get_location().to_str().unwrap_or(self.unknown_output)) + .map_err(|e| LE::new(LEK::FormatError, Some(Box::new(e)))) + }) } } diff --git a/libimagentrylist/src/listers/path.rs b/libimagentrylist/src/listers/path.rs index e3602770..d08e818d 100644 --- a/libimagentrylist/src/listers/path.rs +++ b/libimagentrylist/src/listers/path.rs @@ -5,6 +5,7 @@ use lister::Lister; use result::Result; use libimagstore::store::FileLockEntry; +use libimagutil::iter::fold_ok; pub struct PathLister { absolute: bool, @@ -26,8 +27,8 @@ impl Lister for PathLister { use error::ListError as LE; use error::ListErrorKind as LEK; - entries.fold(Ok(()), |accu, entry| { - accu.and_then(|_| Ok(entry.get_location().clone())) + fold_ok(entries, |entry| { + Ok(entry.get_location().clone()) .and_then(|pb| { if self.absolute { pb.canonicalize().map_err(|e| LE::new(LEK::FormatError, Some(Box::new(e)))) diff --git a/libimagstore/src/hook/aspect.rs b/libimagstore/src/hook/aspect.rs index 38b5cd07..c58f34fb 100644 --- a/libimagstore/src/hook/aspect.rs +++ b/libimagstore/src/hook/aspect.rs @@ -1,4 +1,5 @@ use libimagerror::trace::trace_error; +use libimagutil::iter::fold_ok; use store::FileLockEntry; use storeid::StoreId; @@ -45,29 +46,25 @@ impl StoreIdAccessor for Aspect { return Err(HE::new(HEK::AccessTypeViolation, None)); } - accessors - .iter() - .fold(Ok(()), |acc, accessor| { - acc.and_then(|_| { - let res = match accessor { - &HDA::StoreIdAccess(accessor) => accessor.access(id), - _ => unreachable!(), - }; + fold_ok(accessors.iter(), |accessor| { + let res = match accessor { + &HDA::StoreIdAccess(accessor) => accessor.access(id), + _ => unreachable!(), + }; - match res { - Ok(res) => Ok(res), - Err(e) => { - if !e.is_aborting() { - trace_error(&e); - // ignore error if it is not aborting, as we printed it already - Ok(()) - } else { - Err(e) - } - } + match res { + Ok(res) => Ok(res), + Err(e) => { + if !e.is_aborting() { + trace_error(&e); + // ignore error if it is not aborting, as we printed it already + Ok(()) + } else { + Err(e) } - }) - }) + } + } + }) } } @@ -91,27 +88,25 @@ impl MutableHookDataAccessor for Aspect { // More sophisticated version would check whether there are _chunks_ of // NonMutableAccess accessors and execute these chunks in parallel. We do not have // performance concerns yet, so this is okay. - accessors.iter().fold(Ok(()), |acc, accessor| { - acc.and_then(|_| { - let res = match accessor { - &HDA::MutableAccess(ref accessor) => accessor.access_mut(fle), - &HDA::NonMutableAccess(ref accessor) => accessor.access(fle), - _ => unreachable!(), - }; + fold_ok(accessors.iter(), |accessor| { + let res = match accessor { + &HDA::MutableAccess(ref accessor) => accessor.access_mut(fle), + &HDA::NonMutableAccess(ref accessor) => accessor.access(fle), + _ => unreachable!(), + }; - match res { - Ok(res) => Ok(res), - Err(e) => { - if !e.is_aborting() { - trace_error(&e); - // ignore error if it is not aborting, as we printed it already - Ok(()) - } else { - Err(e) - } + match res { + Ok(res) => Ok(res), + Err(e) => { + if !e.is_aborting() { + trace_error(&e); + // ignore error if it is not aborting, as we printed it already + Ok(()) + } else { + Err(e) } } - }) + } }) } } @@ -123,29 +118,25 @@ impl NonMutableHookDataAccessor for Aspect { return Err(HE::new(HEK::AccessTypeViolation, None)); } - accessors - .iter() - .fold(Ok(()), |acc, accessor| { - acc.and_then(|_| { - let res = match accessor { - &HDA::NonMutableAccess(accessor) => accessor.access(fle), - _ => unreachable!(), - }; + fold_ok(accessors.iter(), |accessor| { + let res = match accessor { + &HDA::NonMutableAccess(accessor) => accessor.access(fle), + _ => unreachable!(), + }; - match res { - Ok(res) => Ok(res), - Err(e) => { - if !e.is_aborting() { - trace_error(&e); - // ignore error if it is not aborting, as we printed it already - Ok(()) - } else { - Err(e) - } - } + match res { + Ok(res) => Ok(res), + Err(e) => { + if !e.is_aborting() { + trace_error(&e); + // ignore error if it is not aborting, as we printed it already + Ok(()) + } else { + Err(e) } - }) - }) + } + } + }) } } diff --git a/libimagstore/src/store.rs b/libimagstore/src/store.rs index 4238eef6..7ca8cd37 100644 --- a/libimagstore/src/store.rs +++ b/libimagstore/src/store.rs @@ -37,6 +37,7 @@ use hook::position::HookPosition; use hook::Hook; use libimagerror::into::IntoError; +use libimagutil::iter::fold_ok; use self::glob_store_iter::*; @@ -692,13 +693,16 @@ impl Store { id: &StoreId) -> HookResult<()> { - match aspects.lock() { - Err(_) => return Err(HookErrorKind::HookExecutionError.into()), - Ok(g) => g - }.iter().fold(Ok(()), |acc, aspect| { - debug!("[Aspect][exec]: {:?}", aspect); - acc.and_then(|_| (aspect as &StoreIdAccessor).access(id)) - }).map_err(Box::new).map_err(|e| HookErrorKind::HookExecutionError.into_error_with_cause(e)) + fold_ok( + match aspects.lock() { + Err(_) => return Err(HookErrorKind::HookExecutionError.into()), + Ok(g) => g + }.iter(), + |aspect| { + debug!("[Aspect][exec]: {:?}", aspect); + (aspect as &StoreIdAccessor).access(id) + }).map_err(Box::new) + .map_err(|e| HookErrorKind::HookExecutionError.into_error_with_cause(e)) } fn execute_hooks_for_mut_file(&self, @@ -706,13 +710,16 @@ impl Store { fle: &mut FileLockEntry) -> HookResult<()> { - match aspects.lock() { - Err(_) => return Err(HookErrorKind::HookExecutionError.into()), - Ok(g) => g - }.iter().fold(Ok(()), |acc, aspect| { - debug!("[Aspect][exec]: {:?}", aspect); - acc.and_then(|_| aspect.access_mut(fle)) - }).map_err(Box::new).map_err(|e| HookErrorKind::HookExecutionError.into_error_with_cause(e)) + fold_ok( + match aspects.lock() { + Err(_) => return Err(HookErrorKind::HookExecutionError.into()), + Ok(g) => g + }.iter(), + |aspect| { + debug!("[Aspect][exec]: {:?}", aspect); + aspect.access_mut(fle) + }).map_err(Box::new) + .map_err(|e| HookErrorKind::HookExecutionError.into_error_with_cause(e)) } } diff --git a/libimagutil/src/iter.rs b/libimagutil/src/iter.rs new file mode 100644 index 00000000..0f682bff --- /dev/null +++ b/libimagutil/src/iter.rs @@ -0,0 +1,8 @@ +/// Processes `iter` returning the last successful result or the first error. +pub fn fold_ok(iter: I, mut func: F) -> Result + where I: Iterator, + R: Default, + F: FnMut(X) -> Result +{ + iter.fold(Ok(R::default()), |acc, item| acc.and_then(|_| func(item))) +} diff --git a/libimagutil/src/lib.rs b/libimagutil/src/lib.rs index bde49b00..730970e8 100644 --- a/libimagutil/src/lib.rs +++ b/libimagutil/src/lib.rs @@ -18,5 +18,6 @@ extern crate regex; pub mod ismatch; +pub mod iter; pub mod key_value_split; pub mod variants;