From b6b9db748879379c0c9915d4e77a8820b289422b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 25 Dec 2019 14:54:10 +0100 Subject: Rewrite "show" Command to be able to read ids from stdin Signed-off-by: Matthias Beyer --- bin/domain/imag-contact/src/lib.rs | 63 ++++++++++++++++++++++++++++++-------- bin/domain/imag-contact/src/ui.rs | 31 +++++++++++++++---- 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/bin/domain/imag-contact/src/lib.rs b/bin/domain/imag-contact/src/lib.rs index 873c822a..5b7a808c 100644 --- a/bin/domain/imag-contact/src/lib.rs +++ b/bin/domain/imag-contact/src/lib.rs @@ -74,6 +74,9 @@ use resiter::Filter; use libimagrt::runtime::Runtime; use libimagrt::application::ImagApplication; +use libimagstore::store::FileLockEntry; +use libimagstore::storeid::StoreId; +use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagcontact::store::ContactStore; use libimagcontact::contact::Contact; use libimagcontact::deser::DeserVcard; @@ -217,28 +220,64 @@ fn import(rt: &Runtime) -> Result<()> { } } -fn show(rt: &Runtime) -> Result<()> { - let scmd = rt.cli().subcommand_matches("show").unwrap(); - let hash = scmd.value_of("hash").map(String::from).unwrap(); // safed by clap - let show_format = get_contact_print_format("contact.show_format", rt, &scmd)?; +fn show_contacts<'a, I>(rt: &Runtime, show_format: &Handlebars, iter: I) -> Result<()> + where I: Iterator>> +{ let out = rt.stdout(); let mut outlock = out.lock(); - util::find_contact_by_hash(rt, hash)? - .filter_ok(|tpl| tpl.0) - .map_ok(|tpl| tpl.1) - .enumerate() + iter.enumerate() .map(|(i, elem)| { - let elem = elem?.deser()?; - let data = build_data_object_for_handlebars(i, &elem); + elem.and_then(|e| { + let elem = e.deser()?; + let data = build_data_object_for_handlebars(i, &elem); - let s = show_format.render("format", &data)?; - writeln!(outlock, "{}", s).map_err(Error::from) + let s = show_format.render("format", &data)?; + writeln!(outlock, "{}", s).map_err(Error::from) + }) }) .collect::>>() .map(|_| ()) } +fn show(rt: &Runtime) -> Result<()> { + let scmd = rt.cli().subcommand_matches("show").unwrap(); + let show_format = get_contact_print_format("contact.show_format", rt, &scmd)?; + + if let Some(ids) = scmd.values_of("ids") { + let ids = ids.collect::>(); + if ids.iter().all(|id| id.starts_with("contact")) { + let iter = ids + .into_iter() + .map(String::from) + .map(PathBuf::from) + .map(StoreId::new) + .into_get_iter(rt.store()) + .map_inner_ok_or_else(|| err_msg("Did not find one entry")); + + show_contacts(rt, &show_format, iter) + } else { + ids + .into_iter() + .map(|hash| util::find_contact_by_hash(rt, hash)) + .collect::>>()? + .into_iter() + .map(|iter| show_contacts(rt, &show_format, iter.filter_ok(|tpl| tpl.0).map_ok(|tpl| tpl.1))) + .collect::>>() + .map(|_| ()) + } + } else { + let iter = rt.ids::()? + .ok_or_else(|| err_msg("No ids supplied"))? + .into_iter() + .map(Ok) + .into_get_iter(rt.store()) + .map_inner_ok_or_else(|| err_msg("Did not find one entry")); + + show_contacts(rt, &show_format, iter) + } +} + fn find(rt: &Runtime) -> Result<()> { let scmd = rt.cli().subcommand_matches("find").unwrap(); let grepstring = scmd diff --git a/bin/domain/imag-contact/src/ui.rs b/bin/domain/imag-contact/src/ui.rs index f60fd17d..4767b175 100644 --- a/bin/domain/imag-contact/src/ui.rs +++ b/bin/domain/imag-contact/src/ui.rs @@ -17,7 +17,13 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use clap::{Arg, App, SubCommand}; +use std::path::PathBuf; + +use clap::{Arg, ArgMatches, App, SubCommand}; +use failure::Fallible as Result; + +use libimagstore::storeid::StoreId; +use libimagrt::runtime::IdPathProvider; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app @@ -76,13 +82,13 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .subcommand(SubCommand::with_name("show") .about("Show contact") .version("0.1") - .arg(Arg::with_name("hash") + .arg(Arg::with_name("ids") .index(1) .takes_value(true) - .required(true) - .multiple(false) - .value_name("HASH") - .help("Show the contact pointed to by this reference hash")) + .required(false) + .multiple(true) + .value_name("ID") + .help("Show the contact pointed to by this reference hash or by the full store id")) .arg(Arg::with_name("format") .long("format") .takes_value(true) @@ -207,3 +213,16 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .help("Don't track the new vcf file if one is created.")) ) } + +pub struct PathProvider; +impl IdPathProvider for PathProvider { + fn get_ids(matches: &ArgMatches) -> Result>> { + if let Some(ids) = matches.values_of("ids") { + ids.map(|i| StoreId::new(PathBuf::from(i))) + .collect::>>() + .map(Some) + } else { + Ok(None) + } + } +} -- cgit v1.2.3