diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2018-03-12 17:07:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-12 17:07:11 +0100 |
commit | 6ec509709dc1d8af444ffbb537a8e5f260e31977 (patch) | |
tree | 7b59b3bf70a7ae265b2ff1b3d4ba7c1ae4d0b48c /bin | |
parent | b374f21d7cecd786948092ae89f0f50113d1b422 (diff) | |
parent | cbe30fa9c296b834a4ba371aa5827d9212f25c61 (diff) |
Merge pull request #1336 from matthiasbeyer/imag-contact/find-show
imag-contact: Add "find" command
Diffstat (limited to 'bin')
-rw-r--r-- | bin/domain/imag-contact/src/main.rs | 77 | ||||
-rw-r--r-- | bin/domain/imag-contact/src/ui.rs | 33 |
2 files changed, 110 insertions, 0 deletions
diff --git a/bin/domain/imag-contact/src/main.rs b/bin/domain/imag-contact/src/main.rs index ba50d1b8..62196f05 100644 --- a/bin/domain/imag-contact/src/main.rs +++ b/bin/domain/imag-contact/src/main.rs @@ -98,6 +98,7 @@ fn main() { "list" => list(&rt), "import" => import(&rt), "show" => show(&rt), + "find" => find(&rt), "create" => create(&rt), _ => { error!("Unknown command"); // More error handling @@ -214,6 +215,82 @@ fn show(rt: &Runtime) { let _ = writeln!(::std::io::stdout(), "{}", s).to_exit_code().unwrap_or_exit(); } +fn find(rt: &Runtime) { + let scmd = rt.cli().subcommand_matches("find").unwrap(); + let grepstring = scmd + .values_of("string") + .unwrap() // safed by clap + .map(String::from) + .collect::<Vec<String>>(); + + // We don't know yet which we need, but we pay that price for simplicity of the codebase + let show_format = get_contact_print_format("contact.show_format", rt, &scmd); + let list_format = get_contact_print_format("contact.list_format", rt, &scmd); + + rt.store() + .all_contacts() + .map_err_trace_exit_unwrap(1) + .into_get_iter(rt.store()) + .map(|el| { + el.map_err_trace_exit_unwrap(1) + .ok_or_else(|| { + error!("Could not get StoreId from Store::all_contacts(). This is a BUG!"); + ::std::process::exit(1) + }) + .unwrap() // safed above + }) + .filter_map(|cont| { + let comp = cont + .get_contact_data() + .map_err_trace_exit_unwrap(1) + .into_inner(); + + let card = Vcard::from_component(comp) + .map_err(|_| { + error!("Could not build Vcard from {:?}", cont.get_location()); + ::std::process::exit(1) + }) + .unwrap(); // safed above + + let str_contains_any = |s: &String, v: &Vec<String>| { + v.iter().any(|i| s.contains(i)) + }; + + let take = card.adr().iter().any(|a| str_contains_any(a.raw(), &grepstring)) + || card.email().iter().any(|a| str_contains_any(a.raw(), &grepstring)) + || card.fullname().iter().any(|a| str_contains_any(a.raw(), &grepstring)); + + if take { + // optimization so we don't have to parse again in the next step + Some((cont, card)) + } else { + None + } + }) + .enumerate() + .for_each(|(i, (fle, card))| { + let fmt = if scmd.is_present("find-show") { + &show_format + } else if scmd.is_present("find-list") { + &list_format + } else { // default: find-list + &list_format + }; + + let hash = fle.get_hash().map(String::from).map_err_trace_exit_unwrap(1); + let data = build_data_object_for_handlebars(i, hash, &card); + let s = fmt + .render("format", &data) + .err_from_str() + .map_err(CE::from) + .map_err_trace_exit_unwrap(1); + + let _ = writeln!(rt.stdout(), "{}", s) + .to_exit_code() + .unwrap_or_exit(); + }); +} + fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd: &ArgMatches) -> Handlebars { let fmt = scmd .value_of("format") diff --git a/bin/domain/imag-contact/src/ui.rs b/bin/domain/imag-contact/src/ui.rs index e1e32701..79149a92 100644 --- a/bin/domain/imag-contact/src/ui.rs +++ b/bin/domain/imag-contact/src/ui.rs @@ -71,6 +71,39 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .help("Format to format the contact when printing it")) ) + .subcommand(SubCommand::with_name("find") + .about("Find contact by grepping for a string (no regex yet)") + .version("0.1") + .arg(Arg::with_name("string") + .index(1) + .takes_value(true) + .required(true) + .multiple(true) + .value_name("grepstring") + .help("Find the contact by grepping for this string")) + + .arg(Arg::with_name("find-show") + .long("show") + .short("s") + .takes_value(false) + .required(false) + .multiple(false) + .help("Show the result") + .conflicts_with("find-list") + ) + + .arg(Arg::with_name("find-list") + .long("list") + .short("l") + .takes_value(false) + .required(false) + .multiple(false) + .help("List the result") + .conflicts_with("find-show") + ) + + ) + .subcommand(SubCommand::with_name("create") .about("Create a contact file (.vcf) and track it in imag.") .version("0.1") |