Move imag-link to ID provider infrastructure

This commit is contained in:
Matthias Beyer 2018-10-01 13:17:19 +02:00
parent 4856541f5a
commit 527e0310ae
2 changed files with 134 additions and 73 deletions

View file

@ -188,81 +188,63 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I)
} }
fn remove_linking(rt: &Runtime) { fn remove_linking(rt: &Runtime) {
let mut from = rt.cli()
fn get_from_entry<'a>(rt: &'a Runtime) -> Option<FileLockEntry<'a>> {
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()
.subcommand_matches("remove") .subcommand_matches("remove")
.unwrap() .unwrap() // safe, we know there is an "remove" subcommand
.values_of("to") .value_of("from")
.map(|values| { .map(PathBuf::from)
for (entry, value) in values.map(|v| (get_entry_by_name(rt, v), v)) { .map(|id| {
match entry { rt.store()
Err(e) => trace_error(&e), .get(id)
Ok(Some(mut to_entry)) => { .map_err_trace_exit_unwrap(1)
let _ = to_entry .ok_or_else(|| warn_exit("No 'from' entry", 1))
.remove_internal_link(&mut from) .unwrap() // safe by line above
.map_err_trace_exit_unwrap(1); })
}, .unwrap();
Ok(None) => {
// looks like this is not an entry, but a filesystem URI and therefor an rt.ids::<::ui::PathProvider>()
// external link...? .map_err_trace_exit_unwrap(1)
if PathBuf::from(value).is_file() { .into_iter()
let url = Url::parse(value).unwrap_or_else(|e| { .for_each(|id| match rt.store().get(id.clone()) {
error!("Error parsing URL: {:?}", e); Err(e) => trace_error(&e),
::std::process::exit(1); Ok(Some(mut to_entry)) => {
}); let _ = to_entry
from.remove_external_link(rt.store(), url).map_err_trace_exit_unwrap(1); .remove_internal_link(&mut from)
info!("Ok: {}", value); .map_err_trace_exit_unwrap(1);
} else { },
warn!("Entry not found: {:?}", value); 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) { fn unlink(rt: &Runtime) {
use libimagerror::iter::TraceIterator; rt.ids::<::ui::PathProvider>().map_err_trace_exit_unwrap(1).into_iter().for_each(|id| {
use libimagstore::iter::get::StoreIdGetIteratorExtension; rt.store()
.get(id.clone())
let _ = rt .map_err_trace_exit_unwrap(1)
.cli() .unwrap_or_else(|| {
.subcommand_matches("unlink") warn!("No entry for {}", id);
.unwrap() // checked in main() ::std::process::exit(1)
.values_of("from") })
.unwrap() // checked by clap .unlink(rt.store())
.map(PathBuf::from) .map_err_trace_exit_unwrap(1)
.collect::<Vec<PathBuf>>().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::<Vec<_>>();
} }
fn list_linkings(rt: &Runtime) { fn list_linkings(rt: &Runtime) {
@ -276,8 +258,8 @@ fn list_linkings(rt: &Runtime) {
let mut tab = ::prettytable::Table::new(); let mut tab = ::prettytable::Table::new();
tab.set_titles(row!["#", "Link"]); tab.set_titles(row!["#", "Link"]);
for entry in cmd.values_of("entries").unwrap() { // safed by clap rt.ids::<::ui::PathProvider>().map_err_trace_exit_unwrap(1).into_iter().for_each(|id| {
match rt.store().get(PathBuf::from(entry)) { match rt.store().get(id.clone()) {
Ok(Some(entry)) => { Ok(Some(entry)) => {
for (i, link) in entry.get_internal_links().map_err_trace_exit_unwrap(1).enumerate() { for (i, link) in entry.get_internal_links().map_err_trace_exit_unwrap(1).enumerate() {
let link = link 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), Err(e) => trace_error(&e),
} }
} });
if !list_plain { if !list_plain {
let out = rt.stdout(); let out = rt.stdout();

View file

@ -17,7 +17,15 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // 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> { pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
app app
@ -101,3 +109,74 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
.requires("from") .requires("from")
.value_name("ENTRIES")) .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<StoreId> {
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::<Result<Vec<_>, _>>()
.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::<Result<Vec<_>, _>>()
.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::<Result<Vec<_>, _>>()
.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()
})
}
}