From 527e0310aeec4dbbc1622ff73fa6561d3bf4323a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 1 Oct 2018 13:17:19 +0200 Subject: [PATCH] Move imag-link to ID provider infrastructure --- bin/core/imag-link/src/main.rs | 126 ++++++++++++++------------------- bin/core/imag-link/src/ui.rs | 81 ++++++++++++++++++++- 2 files changed, 134 insertions(+), 73 deletions(-) diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index ab4a345e..ee9fe426 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -188,81 +188,63 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I) } fn remove_linking(rt: &Runtime) { - - fn get_from_entry<'a>(rt: &'a Runtime) -> Option> { - rt.cli() - .subcommand_matches("remove") - .unwrap() // safe, we know there is an "remove" subcommand - .value_of("from") - .and_then(|from_name| { - match get_entry_by_name(rt, from_name) { - Err(e) => { - debug!("We couldn't get the entry from name: '{:?}'", from_name); - trace_error(&e); None - }, - Ok(Some(e)) => Some(e), - Ok(None) => None, - } - - }) - } - - let mut from = match get_from_entry(&rt) { - None => warn_exit("No 'from' entry", 1), - Some(s) => s, - }; - - rt.cli() + let mut from = rt.cli() .subcommand_matches("remove") - .unwrap() - .values_of("to") - .map(|values| { - for (entry, value) in values.map(|v| (get_entry_by_name(rt, v), v)) { - match entry { - Err(e) => trace_error(&e), - Ok(Some(mut to_entry)) => { - let _ = to_entry - .remove_internal_link(&mut from) - .map_err_trace_exit_unwrap(1); - }, - Ok(None) => { - // looks like this is not an entry, but a filesystem URI and therefor an - // external link...? - if PathBuf::from(value).is_file() { - let url = Url::parse(value).unwrap_or_else(|e| { - error!("Error parsing URL: {:?}", e); - ::std::process::exit(1); - }); - from.remove_external_link(rt.store(), url).map_err_trace_exit_unwrap(1); - info!("Ok: {}", value); - } else { - warn!("Entry not found: {:?}", value); - } - } + .unwrap() // safe, we know there is an "remove" subcommand + .value_of("from") + .map(PathBuf::from) + .map(|id| { + rt.store() + .get(id) + .map_err_trace_exit_unwrap(1) + .ok_or_else(|| warn_exit("No 'from' entry", 1)) + .unwrap() // safe by line above + }) + .unwrap(); + + rt.ids::<::ui::PathProvider>() + .map_err_trace_exit_unwrap(1) + .into_iter() + .for_each(|id| match rt.store().get(id.clone()) { + Err(e) => trace_error(&e), + Ok(Some(mut to_entry)) => { + let _ = to_entry + .remove_internal_link(&mut from) + .map_err_trace_exit_unwrap(1); + }, + Ok(None) => { + // looks like this is not an entry, but a filesystem URI and therefor an + // external link...? + if id.local().is_file() { + let pb = id.local().to_str().unwrap_or_else(|| { + warn!("Not StoreId and not a Path: {}", id); + ::std::process::exit(1); + }); + let url = Url::parse(pb).unwrap_or_else(|e| { + error!("Error parsing URL: {:?}", e); + ::std::process::exit(1); + }); + from.remove_external_link(rt.store(), url).map_err_trace_exit_unwrap(1); + info!("Ok: {}", id); + } else { + warn!("Entry not found: {:?}", id); } } }); } fn unlink(rt: &Runtime) { - use libimagerror::iter::TraceIterator; - use libimagstore::iter::get::StoreIdGetIteratorExtension; - - let _ = rt - .cli() - .subcommand_matches("unlink") - .unwrap() // checked in main() - .values_of("from") - .unwrap() // checked by clap - .map(PathBuf::from) - .collect::>().into_iter() // for lifetime inference - .map(StoreId::new_baseless) - .into_get_iter(rt.store()) - .trace_unwrap_exit(1) - .filter_map(|x| x) - .map(|mut entry| entry.unlink(rt.store())) - .trace_unwrap_exit(1) - .collect::>(); + rt.ids::<::ui::PathProvider>().map_err_trace_exit_unwrap(1).into_iter().for_each(|id| { + rt.store() + .get(id.clone()) + .map_err_trace_exit_unwrap(1) + .unwrap_or_else(|| { + warn!("No entry for {}", id); + ::std::process::exit(1) + }) + .unlink(rt.store()) + .map_err_trace_exit_unwrap(1) + }); } fn list_linkings(rt: &Runtime) { @@ -276,8 +258,8 @@ fn list_linkings(rt: &Runtime) { let mut tab = ::prettytable::Table::new(); tab.set_titles(row!["#", "Link"]); - for entry in cmd.values_of("entries").unwrap() { // safed by clap - match rt.store().get(PathBuf::from(entry)) { + rt.ids::<::ui::PathProvider>().map_err_trace_exit_unwrap(1).into_iter().for_each(|id| { + match rt.store().get(id.clone()) { Ok(Some(entry)) => { for (i, link) in entry.get_internal_links().map_err_trace_exit_unwrap(1).enumerate() { let link = link @@ -315,10 +297,10 @@ fn list_linkings(rt: &Runtime) { }) } }, - Ok(None) => warn!("Not found: {}", entry), + Ok(None) => warn!("Not found: {}", id), Err(e) => trace_error(&e), } - } + }); if !list_plain { let out = rt.stdout(); diff --git a/bin/core/imag-link/src/ui.rs b/bin/core/imag-link/src/ui.rs index 3f3136eb..5ca5fca6 100644 --- a/bin/core/imag-link/src/ui.rs +++ b/bin/core/imag-link/src/ui.rs @@ -17,7 +17,15 @@ // 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 libimagstore::storeid::StoreId; +use libimagstore::storeid::IntoStoreId; +use libimagrt::runtime::IdPathProvider; +use libimagerror::trace::MapErrTrace; + pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app @@ -101,3 +109,74 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .requires("from") .value_name("ENTRIES")) } + +/// PathProvider +/// +/// This PathProvider does _not_ return the "from" value of the commandline call if no subcommand +/// is given. +/// +/// It has to be fetched by main() by hand. +pub struct PathProvider; +impl IdPathProvider for PathProvider { + fn get_ids(matches: &ArgMatches) -> Vec { + let ids = match matches.subcommand() { + ("remove", Some(subm)) => { + let to = subm.values_of("to") + .ok_or_else(|| { + error!("No StoreId found"); + ::std::process::exit(1) + }) + .unwrap() + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::, _>>() + .map_err_trace_exit_unwrap(1); + Some(to) + }, + + ("unlink", Some(subm)) => { + let ids = subm + .values_of("from") + .ok_or_else(|| { + error!("No StoreId found"); + ::std::process::exit(1) + }) + .unwrap() + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::, _>>() + .map_err_trace_exit_unwrap(1); + + Some(ids) + }, + + ("list", Some(subm)) => { + let ids = subm + .values_of("entries") + .ok_or_else(|| { + error!("No StoreId found"); + ::std::process::exit(1) + }) + .unwrap() + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::, _>>() + .map_err_trace_exit_unwrap(1); + + Some(ids) + }, + + _ => None, + }; + + ids.unwrap_or_else(|| { + matches.values_of("to") + .unwrap() + .map(|s| PathBuf::from(s).into_storeid().map_err_trace_exit_unwrap(1)) + .collect() + }) + } +}