~matthiasbeyer/imag

6c0e983a816dcb02e85ed1fb16f24ad94ac098b4 — Matthias Beyer 1 year, 1 month ago 427307e + ad7d8bf
Merge branch 'viewing-iterator' into master

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2 files changed, 74 insertions(+), 0 deletions(-)

M lib/entry/libimagentryview/src/lib.rs
M lib/entry/libimagentryview/src/viewer.rs
M lib/entry/libimagentryview/src/lib.rs => lib/entry/libimagentryview/src/lib.rs +1 -0
@@ 37,6 37,7 @@
    while_true,
)]

#[macro_use] extern crate log;
extern crate toml;
extern crate textwrap;
extern crate failure;

M lib/entry/libimagentryview/src/viewer.rs => lib/entry/libimagentryview/src/viewer.rs +73 -0
@@ 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
    }
}