Move from a helper function to a typeclass.
This introduces the `FoldResut` trait to move from `func(receiver, ...)` style to `receiver.func(...)` style. Also add a means to pass the default result explicitly.
This commit is contained in:
parent
2c40b8734e
commit
7f57e5e234
5 changed files with 54 additions and 36 deletions
|
@ -5,7 +5,7 @@ use lister::Lister;
|
|||
use result::Result;
|
||||
|
||||
use libimagstore::store::FileLockEntry;
|
||||
use libimagutil::iter::fold_ok;
|
||||
use libimagutil::iter::FoldResult;
|
||||
|
||||
pub struct LineLister<'a> {
|
||||
unknown_output: &'a str,
|
||||
|
@ -27,7 +27,7 @@ impl<'a> Lister for LineLister<'a> {
|
|||
use error::ListError as LE;
|
||||
use error::ListErrorKind as LEK;
|
||||
|
||||
fold_ok(entries, |entry| {
|
||||
entries.fold_defresult(|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))))
|
||||
})
|
||||
|
|
|
@ -5,7 +5,7 @@ use lister::Lister;
|
|||
use result::Result;
|
||||
|
||||
use libimagstore::store::FileLockEntry;
|
||||
use libimagutil::iter::fold_ok;
|
||||
use libimagutil::iter::FoldResult;
|
||||
|
||||
pub struct PathLister {
|
||||
absolute: bool,
|
||||
|
@ -27,7 +27,7 @@ impl Lister for PathLister {
|
|||
use error::ListError as LE;
|
||||
use error::ListErrorKind as LEK;
|
||||
|
||||
fold_ok(entries, |entry| {
|
||||
entries.fold_defresult(|entry| {
|
||||
Ok(entry.get_location().clone())
|
||||
.and_then(|pb| {
|
||||
if self.absolute {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use libimagerror::trace::trace_error;
|
||||
use libimagutil::iter::fold_ok;
|
||||
use libimagutil::iter::FoldResult;
|
||||
|
||||
use store::FileLockEntry;
|
||||
use storeid::StoreId;
|
||||
|
@ -46,7 +46,7 @@ impl StoreIdAccessor for Aspect {
|
|||
return Err(HE::new(HEK::AccessTypeViolation, None));
|
||||
}
|
||||
|
||||
fold_ok(accessors.iter(), |accessor| {
|
||||
accessors.iter().fold_defresult(|accessor| {
|
||||
let res = match accessor {
|
||||
&HDA::StoreIdAccess(accessor) => accessor.access(id),
|
||||
_ => unreachable!(),
|
||||
|
@ -88,7 +88,7 @@ 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.
|
||||
fold_ok(accessors.iter(), |accessor| {
|
||||
accessors.iter().fold_defresult(|accessor| {
|
||||
let res = match accessor {
|
||||
&HDA::MutableAccess(ref accessor) => accessor.access_mut(fle),
|
||||
&HDA::NonMutableAccess(ref accessor) => accessor.access(fle),
|
||||
|
@ -118,7 +118,7 @@ impl NonMutableHookDataAccessor for Aspect {
|
|||
return Err(HE::new(HEK::AccessTypeViolation, None));
|
||||
}
|
||||
|
||||
fold_ok(accessors.iter(), |accessor| {
|
||||
accessors.iter().fold_defresult(|accessor| {
|
||||
let res = match accessor {
|
||||
&HDA::NonMutableAccess(accessor) => accessor.access(fle),
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -37,7 +37,7 @@ use hook::position::HookPosition;
|
|||
use hook::Hook;
|
||||
|
||||
use libimagerror::into::IntoError;
|
||||
use libimagutil::iter::fold_ok;
|
||||
use libimagutil::iter::FoldResult;
|
||||
|
||||
use self::glob_store_iter::*;
|
||||
|
||||
|
@ -693,16 +693,14 @@ impl Store {
|
|||
id: &StoreId)
|
||||
-> HookResult<()>
|
||||
{
|
||||
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))
|
||||
match aspects.lock() {
|
||||
Err(_) => return Err(HookErrorKind::HookExecutionError.into()),
|
||||
Ok(g) => g
|
||||
}.iter().fold_defresult(|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,
|
||||
|
@ -710,16 +708,14 @@ impl Store {
|
|||
fle: &mut FileLockEntry)
|
||||
-> HookResult<()>
|
||||
{
|
||||
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))
|
||||
match aspects.lock() {
|
||||
Err(_) => return Err(HookErrorKind::HookExecutionError.into()),
|
||||
Ok(g) => g
|
||||
}.iter().fold_defresult(|aspect| {
|
||||
debug!("[Aspect][exec]: {:?}", aspect);
|
||||
aspect.access_mut(fle)
|
||||
}).map_err(Box::new)
|
||||
.map_err(|e| HookErrorKind::HookExecutionError.into_error_with_cause(e))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,30 @@
|
|||
/// Processes `iter` returning the last successful result or the first error.
|
||||
pub fn fold_ok<X, I, R, E, F>(iter: I, mut func: F) -> Result<R, E>
|
||||
where I: Iterator<Item = X>,
|
||||
R: Default,
|
||||
F: FnMut(X) -> Result<R, E>
|
||||
{
|
||||
iter.fold(Ok(R::default()), |acc, item| acc.and_then(|_| func(item)))
|
||||
/// Folds its contents to a result.
|
||||
pub trait FoldResult: Sized {
|
||||
type Item;
|
||||
|
||||
/// Processes all contained items returning the last successful result or the first error.
|
||||
/// If there are no items, returns `Ok(R::default())`.
|
||||
fn fold_defresult<R, E, F>(self, func: F) -> Result<R, E>
|
||||
where R: Default,
|
||||
F: FnMut(Self::Item)
|
||||
-> Result<R, E>
|
||||
{
|
||||
self.fold_result(R::default(), func)
|
||||
}
|
||||
|
||||
/// Processes all contained items returning the last successful result or the first error.
|
||||
/// If there are no items, returns `Ok(default)`.
|
||||
fn fold_result<R, E, F>(self, default: R, mut func: F) -> Result<R, E>
|
||||
where F: FnMut(Self::Item) -> Result<R, E>;
|
||||
}
|
||||
|
||||
impl<X, I: Iterator<Item = X>> FoldResult for I {
|
||||
type Item = X;
|
||||
|
||||
fn fold_result<R, E, F>(self, default: R, mut func: F) -> Result<R, E>
|
||||
where F: FnMut(Self::Item) -> Result<R, E>
|
||||
{
|
||||
self.fold(Ok(default), |acc, item| acc.and_then(|_| func(item)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue