From 6055520519a704284dacc37412114acb9344e632 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 25 Feb 2018 17:04:05 +0100 Subject: [PATCH 1/2] Provide unlink() to remove all links --- lib/entry/libimagentrylink/src/internal.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/entry/libimagentrylink/src/internal.rs b/lib/entry/libimagentrylink/src/internal.rs index 42f845dc..10482256 100644 --- a/lib/entry/libimagentrylink/src/internal.rs +++ b/lib/entry/libimagentrylink/src/internal.rs @@ -24,6 +24,7 @@ use std::path::PathBuf; use libimagstore::storeid::StoreId; use libimagstore::storeid::IntoStoreId; use libimagstore::store::Entry; +use libimagstore::store::Store; use libimagstore::store::Result as StoreResult; use toml_query::read::TomlValueReadExt; @@ -178,6 +179,9 @@ pub trait InternalLinker { /// Remove an internal link from the implementor object fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()>; + /// Remove _all_ internal links + fn unlink(&mut self, store: &Store) -> Result<()>; + /// Add internal annotated link fn add_internal_annotated_link(&mut self, link: &mut Entry, annotation: String) -> Result<()>; } @@ -452,6 +456,17 @@ impl InternalLinker for Entry { }) } + fn unlink(&mut self, store: &Store) -> Result<()> { + for id in self.get_internal_links()?.map(|l| l.get_store_id().clone()) { + match store.get(id).map_err(LE::from)? { + Some(mut entry) => self.remove_internal_link(&mut entry)?, + None => return Err(LEK::LinkTargetDoesNotExist.into()), + } + } + + Ok(()) + } + fn add_internal_annotated_link(&mut self, link: &mut Entry, annotation: String) -> Result<()> { let new_link = Link::Annotated { link: link.get_location().clone(), From 35ac7ba927b7328e13a67f2de55d9ceedb0d6809 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 25 Feb 2018 17:27:50 +0100 Subject: [PATCH 2/2] Provide unlink() CLI interface --- bin/core/imag-link/src/main.rs | 24 ++++++++++++++++++++++++ bin/core/imag-link/src/ui.rs | 11 +++++++++++ 2 files changed, 35 insertions(+) diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index dbd62bae..271f64ab 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -52,6 +52,7 @@ extern crate libimagutil; use std::io::Write; use std::path::PathBuf; +use std::process::exit; use libimagentrylink::external::ExternalLinker; use libimagentrylink::internal::InternalLinker; @@ -99,6 +100,7 @@ fn main() { .map(|name| { match name { "remove" => remove_linking(&rt), + "unlink" => unlink(&rt), "list" => list_linkings(&rt), _ => panic!("BUG"), } @@ -224,6 +226,28 @@ fn remove_linking(rt: &Runtime) { }); } +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) + .unwrap_with(|e| { trace_error(&e); exit(1) }) + .into_get_iter(rt.store()) + .unwrap_with(|e| { trace_error(&e); exit(1) }) + .filter_map(|e| e) + .map(|mut entry| entry.unlink(rt.store())) + .unwrap_with(|e| { trace_error(&e); exit(1) }) + .collect::>(); +} + fn list_linkings(rt: &Runtime) { let cmd = rt.cli() .subcommand_matches("list") diff --git a/bin/core/imag-link/src/ui.rs b/bin/core/imag-link/src/ui.rs index f99575ab..f43812ce 100644 --- a/bin/core/imag-link/src/ui.rs +++ b/bin/core/imag-link/src/ui.rs @@ -39,6 +39,17 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .help("Remove links to these entries") .value_name("ENTRIES")) ) + .subcommand(SubCommand::with_name("unlink") + .about("Remove all links from an entry") + .version("0.1") + .arg(Arg::with_name("from") + .index(1) + .takes_value(true) + .required(true) + .multiple(true) + .help("Remove links from these entries") + .value_name("ENTRY")) + ) .subcommand(SubCommand::with_name("list") .about("List links to this entry")