summaryrefslogtreecommitdiffstats
path: root/libimagentrylist
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2016-08-02 16:28:32 +0200
committerMatthias Beyer <mail@beyermatthias.de>2016-08-02 16:28:32 +0200
commit9fd65dbe4a36d390bf55f51d80b5277d34e9a5e1 (patch)
tree0bc632beb6aa608d21614d922c5382ddf8ace62d /libimagentrylist
parente88082f270384a925df673c93bef17bd088f4e14 (diff)
Add TableLister
Diffstat (limited to 'libimagentrylist')
-rw-r--r--libimagentrylist/src/listers/mod.rs1
-rw-r--r--libimagentrylist/src/listers/table.rs91
2 files changed, 92 insertions, 0 deletions
diff --git a/libimagentrylist/src/listers/mod.rs b/libimagentrylist/src/listers/mod.rs
index d4e06f93..4c43b657 100644
--- a/libimagentrylist/src/listers/mod.rs
+++ b/libimagentrylist/src/listers/mod.rs
@@ -1,3 +1,4 @@
pub mod core;
pub mod line;
pub mod path;
+pub mod table;
diff --git a/libimagentrylist/src/listers/table.rs b/libimagentrylist/src/listers/table.rs
new file mode 100644
index 00000000..231f708d
--- /dev/null
+++ b/libimagentrylist/src/listers/table.rs
@@ -0,0 +1,91 @@
+use std::io::stdout;
+
+use lister::Lister;
+use result::Result;
+use error::MapErrInto;
+
+use libimagstore::store::FileLockEntry;
+use libimagerror::into::IntoError;
+
+use prettytable::Table;
+use prettytable::cell::Cell;
+use prettytable::row::Row;
+
+pub struct TableLister<F: Fn(&FileLockEntry) -> Vec<String>> {
+ line_generator: F,
+ header: Option<Vec<String>>,
+
+ with_idx: bool,
+}
+
+impl<F: Fn(&FileLockEntry) -> Vec<String>> TableLister<F> {
+
+ pub fn new(gen: F) -> TableLister<F> {
+ TableLister {
+ line_generator: gen,
+ header: None,
+ with_idx: true,
+ }
+ }
+
+ pub fn with_header(mut self, hdr: Vec<String>) -> TableLister<F> {
+ self.header = Some(hdr);
+ self
+ }
+
+ pub fn with_idx(mut self, b: bool) -> TableLister<F> {
+ self.with_idx = b;
+ self
+ }
+
+}
+
+impl<F: Fn(&FileLockEntry) -> Vec<String>> Lister for TableLister<F> {
+
+ fn list<'b, I: Iterator<Item = FileLockEntry<'b>>>(&self, entries: I) -> Result<()> {
+ use error::ListErrorKind as LEK;
+
+ let mut table = Table::new();
+ let mut header_len : Option<usize> = None;
+ match self.header {
+ Some(ref s) => {
+ debug!("We have a header... preparing");
+ let mut cells : Vec<Cell> = s.iter().map(|s| Cell::new(s)).collect();
+ if self.with_idx {
+ cells.insert(0, Cell::new("#"));
+ }
+ table.set_titles(Row::new(cells));
+ header_len = Some(s.len());
+ },
+ None => {
+ debug!("No header for table found... continuing without");
+ },
+ }
+
+ entries.fold(Ok(table), |table, entry| {
+ table.and_then(|mut table| {
+ let mut v = (self.line_generator)(&entry);
+ {
+ let v_len = v.len();
+ if header_len.is_none() {
+ header_len = Some(v_len);
+ }
+ if header_len.map(|l| v_len > l).unwrap_or(false) {
+ return Err(LEK::FormatError.into_error());
+ }
+ while header_len.map(|l| v.len() != l).unwrap_or(false) {
+ v.push(String::from(""));
+ }
+ }
+
+ table.add_row(v.iter().map(|s| Cell::new(s)).collect());
+ Ok(table)
+ })
+ })
+ .and_then(|tbl| {
+ let mut io = stdout();
+ tbl.print(&mut io).map_err_into(LEK::IOError)
+ })
+ }
+
+}