diff options
-rw-r--r-- | lib/entry/libimagentryview/src/lib.rs | 1 | ||||
-rw-r--r-- | lib/entry/libimagentryview/src/viewer.rs | 73 |
2 files changed, 74 insertions, 0 deletions
diff --git a/lib/entry/libimagentryview/src/lib.rs b/lib/entry/libimagentryview/src/lib.rs index 328e5113..485aaec8 100644 --- a/lib/entry/libimagentryview/src/lib.rs +++ b/lib/entry/libimagentryview/src/lib.rs @@ -37,6 +37,7 @@ while_true, )] +#[macro_use] extern crate log; extern crate toml; extern crate textwrap; extern crate failure; diff --git a/lib/entry/libimagentryview/src/viewer.rs b/lib/entry/libimagentryview/src/viewer.rs index 902c9b7f..1fa2271c 100644 --- a/lib/entry/libimagentryview/src/viewer.rs +++ b/lib/entry/libimagentryview/src/viewer.rs @@ -21,6 +21,7 @@ use std::io::Write; use std::ops::Deref; use libimagstore::store::Entry; +use libimagstore::store::FileLockEntry; use crate::error::Result; @@ -76,3 +77,75 @@ impl<I, E> ViewFromIter for I } } +pub trait IntoViewIter<V, W, F, T> + where Self: Iterator<Item = T> + Sized, + V: Viewer, + W: Write, + F: Fn(&T) -> Option<&FileLockEntry>, + T: Sized, +{ + fn view_all_if(self, v: V, sink: &mut W, func: F) -> ViewIter<Self, V, W, F, T> { + ViewIter { + inner: self, + viewer: v, + func, + sink, + } + } +} + +impl<I, V, W, F, T> IntoViewIter<V, W, F, T> for I + where I: Iterator<Item = T>, + V: Viewer, + W: Write, + F: Fn(&T) -> Option<&FileLockEntry>, + T: Sized, +{ + // default impl +} + + +pub struct ViewIter<'a, I, V, W, F, T> + where I: Iterator<Item = T>, + V: Viewer, + W: Write, + F: Fn(&T) -> Option<&FileLockEntry>, + T: Sized, +{ + inner: I, + viewer: V, + func: F, + sink: &'a mut W +} + +impl<'a, I, V, W, F, T> Iterator for ViewIter<'a, I, V, W, F, T> + where I: Iterator<Item = T>, + V: Viewer, + W: Write, + F: Fn(&T) -> Option<&FileLockEntry>, + T: Sized, +{ + type Item = failure::Fallible<T>; + + fn next(&mut self) -> Option<Self::Item> { + if let Some(next) = self.inner.next() { + if let Some(entry) = (self.func)(&next) { + let r = self.viewer.view_entry(&entry, self.sink); + trace!("Viewing resulted in {:?}", r); + match r { + Ok(_) => { /* nothing */ }, + Err(crate::error::Error::Io(ref e)) if e.kind() == std::io::ErrorKind::BrokenPipe => { + trace!("Stopping iteration, because of broken pipe error!"); + return None + }, + Err(e) => return Some(Err(failure::Error::from(e))) + } + } + + return Some(Ok(next)) + } + + None + } +} + |