diff --git a/imag-counter/src/list.rs b/imag-counter/src/list.rs new file mode 100644 index 00000000..abb14fda --- /dev/null +++ b/imag-counter/src/list.rs @@ -0,0 +1,35 @@ +use libimagrt::runtime::Runtime; +use libimagutil::trace::trace_error; +use libimagcounter::counter::Counter; +use libimagcounter::result::Result; + +pub fn list(rt: &Runtime) { + rt.cli() + .subcommand_matches("list") + .map(|scmd| { + debug!("Found 'list' subcommand..."); + + Counter::all_counters(rt.store()).map(|iterator| { + for counter in iterator { + counter.map(|c| { + let name = c.name(); + let value = c.value(); + + if name.is_err() { + trace_error(&name.err().unwrap()); + } else { + + if value.is_err() { + trace_error(&value.err().unwrap()); + } else { + println!("{} - {}", name.unwrap(), value.unwrap()); + } + } + }) + .map_err(|e| trace_error(&e)); + } + }) + .map_err(|e| trace_error(&e)) + + }); +} diff --git a/imag-counter/src/main.rs b/imag-counter/src/main.rs index 961db48c..8e62be23 100644 --- a/imag-counter/src/main.rs +++ b/imag-counter/src/main.rs @@ -17,12 +17,14 @@ use libimagutil::key_value_split::IntoKeyValue; mod create; mod delete; mod interactive; +mod list; mod ui; use ui::build_ui; use create::create; use delete::delete; use interactive::interactive; +use list::list; enum Action { Inc, @@ -126,6 +128,7 @@ fn main() { "create" => create(&rt), "delete" => delete(&rt), "interactive" => interactive(&rt), + "list" => list(&rt), _ => { debug!("Unknown command"); // More error handling }, diff --git a/imag-counter/src/ui.rs b/imag-counter/src/ui.rs index 994bb65e..2e6d18ef 100644 --- a/imag-counter/src/ui.rs +++ b/imag-counter/src/ui.rs @@ -54,6 +54,38 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(true) .help("Create counter with this name"))) + .subcommand(SubCommand::with_name("list") + .about("List counters") + .version("0.1") + .arg(Arg::with_name("name") + .long("name") + .short("n") + .takes_value(true) + .required(false) + .help("List counters with this name (foo/bar and baz/bar would match 'bar')")) + + .arg(Arg::with_name("greater-than") + .long("greater") + .short("g") + .takes_value(true) + .required(false) + .help("List counters which are greater than VALUE")) + + .arg(Arg::with_name("lower-than") + .long("lower") + .short("l") + .takes_value(true) + .required(false) + .help("List counters which are lower than VALUE")) + + .arg(Arg::with_name("equals") + .long("equal") + .short("e") + .takes_value(true) + .required(false) + .help("List counters which equal VALUE")) + ) + .subcommand(SubCommand::with_name("interactive") .about("Interactively count things") .version("0.1") diff --git a/libimagcounter/src/counter.rs b/libimagcounter/src/counter.rs index d233e80d..18d5ca30 100644 --- a/libimagcounter/src/counter.rs +++ b/libimagcounter/src/counter.rs @@ -8,6 +8,7 @@ use toml::Value; use std::collections::BTreeMap; use libimagstore::store::Store; +use libimagstore::storeid::StoreIdIterator; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreId; use libimagstore::error::StoreError; @@ -140,5 +141,55 @@ impl<'a> Counter<'a> { store.delete(ModuleEntryPath::new(name).into_storeid()) .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e)))) } + + pub fn all_counters(store: &Store) -> Result { + store.retrieve_for_module("counter") + .map(|iter| CounterIterator::new(store, iter)) + .map_err(|e| CE::new(CEK::StoreReadError, Some(Box::new(e)))) + } + +} + +trait FromStoreId { + fn from_storeid<'a>(&'a Store, StoreId) -> Result>; +} + +impl<'a> FromStoreId for Counter<'a> { + + fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result> { + debug!("Loading counter from storeid: '{:?}'", id); + match store.retrieve(id) { + Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))), + Ok(c) => Ok(Counter { fle: c }), + } + } + +} + +pub struct CounterIterator<'a> { + store: &'a Store, + iditer: StoreIdIterator, +} + +impl<'a> CounterIterator<'a> { + + pub fn new(store: &'a Store, iditer: StoreIdIterator) -> CounterIterator<'a> { + CounterIterator { + store: store, + iditer: iditer, + } + } + +} + +impl<'a> Iterator for CounterIterator<'a> { + type Item = Result>; + + fn next(&mut self) -> Option>> { + self.iditer + .next() + .map(|id| Counter::from_storeid(self.store, id)) + } + }