diff options
author | Leon Schuermann <leon.git@is.currently.online> | 2019-05-18 02:42:38 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2019-05-24 21:03:34 +0200 |
commit | ed457495c8c2e1f0d8caff919cd09fe238baa6b3 (patch) | |
tree | 834cfd07969c4a888915fab0e701571e6a78458e | |
parent | fcdded90b26b4b9d5c23032c8a3282e41aa08887 (diff) |
Introduce proper error handling in IdPathProvider
Prior to this change, the IdPathProvider implementation would be
responsible for exiting the process on insufficient / wrong arguments.
However, such error handling should be performed together with the
business logic and not in CLI-parsing related code.
This change introduces a clear separation: both parsing errors and
insufficient id path arguments can now be return from inside the
`get_ids`-method, and get passed up to the application logic to be
handled.
This change is reflected in all instances of IdPathProvider and their
surrounding code.
Signed-off-by: Leon Schuermann <leon.git@is.currently.online>
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
29 files changed, 378 insertions, 411 deletions
diff --git a/bin/core/imag-annotate/src/main.rs b/bin/core/imag-annotate/src/main.rs index f4ad2093..5904b345 100644 --- a/bin/core/imag-annotate/src/main.rs +++ b/bin/core/imag-annotate/src/main.rs @@ -96,8 +96,15 @@ fn main() { } fn add(rt: &Runtime) { - let scmd = rt.cli().subcommand_matches("add").unwrap(); // safed by main() - let mut ids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap().into_iter(); + let scmd = rt.cli().subcommand_matches("add").unwrap(); // safed by main() + let mut ids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No StoreId supplied"); + ::std::process::exit(1); + }) + .into_iter(); if let Some(first) = ids.next() { let mut annotation = rt.store() @@ -141,10 +148,17 @@ fn add(rt: &Runtime) { } fn remove(rt: &Runtime) { - let scmd = rt.cli().subcommand_matches("remove").unwrap(); // safed by main() + let scmd = rt.cli().subcommand_matches("remove").unwrap(); // safed by main() let annotation_name = scmd.value_of("annotation_name").unwrap(); // safed by clap - let delete = scmd.is_present("delete-annotation"); - let ids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap(); + let delete = scmd.is_present("delete-annotation"); + let ids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .into_iter(); ids.into_iter().for_each(|id| { let mut entry = rt.store() @@ -179,9 +193,16 @@ fn remove(rt: &Runtime) { } fn list(rt: &Runtime) { - let scmd = rt.cli().subcommand_matches("list").unwrap(); // safed by clap + let scmd = rt.cli().subcommand_matches("list").unwrap(); // safed by clap let with_text = scmd.is_present("list-with-text"); - let ids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap(); + let ids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .into_iter(); if ids.len() != 0 { let _ = ids diff --git a/bin/core/imag-annotate/src/ui.rs b/bin/core/imag-annotate/src/ui.rs index 72074c08..2ad23262 100644 --- a/bin/core/imag-annotate/src/ui.rs +++ b/bin/core/imag-annotate/src/ui.rs @@ -24,7 +24,8 @@ use clap::{Arg, ArgMatches, App, SubCommand}; use libimagstore::storeid::StoreId; use libimagstore::storeid::IntoStoreId; use libimagrt::runtime::IdPathProvider; -use libimagerror::trace::MapErrTrace; + +use failure::Fallible as Result; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app @@ -97,53 +98,24 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { pub struct PathProvider; impl IdPathProvider for PathProvider { - fn get_ids(matches: &ArgMatches) -> Vec<StoreId> { - match matches.subcommand() { - ("add", Some(subm)) => { - subm.values_of("entry") - .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() - }, - - ("remove", Some(subm)) => { - subm.values_of("entry") - .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() - }, - - ("list", Some(subm)) => { - subm.values_of("entry") - .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() - }, + fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + fn get_id_paths(subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + subm.values_of("entry") + .map(|v| v + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::<Result<Vec<_>>>() + ) + .transpose() + } + match matches.subcommand() { + ("add", Some(subm)) => get_id_paths(subm), + ("remove", Some(subm)) => get_id_paths(subm), + ("list", Some(subm)) => get_id_paths(subm), (other, _) => { - error!("Not a known command: {}", other); - ::std::process::exit(1) + Err(format_err!("Not a known command: {}", other)) } } } diff --git a/bin/core/imag-category/Cargo.toml b/bin/core/imag-category/Cargo.toml index ad460881..5970ba66 100644 --- a/bin/core/imag-category/Cargo.toml +++ b/bin/core/imag-category/Cargo.toml @@ -23,6 +23,7 @@ maintenance = { status = "actively-developed" } log = "0.4.0" toml = "0.4" toml-query = "0.8" +failure = "0.1" libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-category/src/main.rs b/bin/core/imag-category/src/main.rs index 9629da7f..633729d1 100644 --- a/bin/core/imag-category/src/main.rs +++ b/bin/core/imag-category/src/main.rs @@ -37,6 +37,8 @@ extern crate clap; #[macro_use] extern crate log; +#[macro_use] +extern crate failure; extern crate libimagentrycategory; extern crate libimagerror; @@ -92,7 +94,14 @@ fn main() { fn set(rt: &Runtime) { let scmd = rt.cli().subcommand_matches("set").unwrap(); // safed by main() let name = scmd.value_of("set-name").map(String::from).unwrap(); // safed by clap - let sids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap(); + let sids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .into_iter(); StoreIdIterator::new(Box::new(sids.into_iter().map(Ok))) .into_get_iter(rt.store()) @@ -109,9 +118,16 @@ fn set(rt: &Runtime) { } fn get(rt: &Runtime) { - let sids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap(); - let out = rt.stdout(); + let out = rt.stdout(); let mut outlock = out.lock(); + let sids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .into_iter(); StoreIdIterator::new(Box::new(sids.into_iter().map(Ok))) .into_get_iter(rt.store()) diff --git a/bin/core/imag-category/src/ui.rs b/bin/core/imag-category/src/ui.rs index fca41bd0..f25aeca0 100644 --- a/bin/core/imag-category/src/ui.rs +++ b/bin/core/imag-category/src/ui.rs @@ -20,11 +20,11 @@ use std::path::PathBuf; use clap::{Arg, ArgMatches, App, SubCommand}; +use failure::Fallible as Result; 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 @@ -103,60 +103,30 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { pub struct PathProvider; impl IdPathProvider for PathProvider { - fn get_ids(matches: &ArgMatches) -> Vec<StoreId> { - match matches.subcommand() { - ("create-category", _) => { - error!("Command does not get IDs as input"); - ::std::process::exit(1) - }, - - ("delete-category", _) => { - error!("Command does not get IDs as input"); - ::std::process::exit(1) - }, - - ("list-categories", _) => { - error!("Command does not get IDs as input"); - ::std::process::exit(1) - }, - - ("list-category", _) => { - error!("Command does not get IDs as input"); - ::std::process::exit(1) - }, - - ("set", Some(subm)) => { - subm.values_of("set-ids") - .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() - }, + fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + fn no_ids_error() -> Result<Option<Vec<StoreId>>> { + Err(format_err!("Command does not get IDs as input")) + } - ("get", Some(subm)) => { - subm.values_of("get-ids") - .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() - }, + fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + subm.values_of(field) + .map(|v| v + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::<Result<Vec<_>>>() + ) + .transpose() + } - (other, _) => { - error!("Not a known command: {}", other); - ::std::process::exit(1) - } + match matches.subcommand() { + ("create-category", _) => no_ids_error(), + ("delete-category", _) => no_ids_error(), + ("list-categories", _) => no_ids_error(), + ("list-category", _) => no_ids_error(), + ("set", Some(subm)) => get_id_paths("set-ids", subm), + ("get", Some(subm)) => get_id_paths("get-ids", subm), + (other, _) => Err(format_err!("Not a known command: {}", other)), } } } diff --git a/bin/core/imag-edit/Cargo.toml b/bin/core/imag-edit/Cargo.toml index 7900ae69..af118f84 100644 --- a/bin/core/imag-edit/Cargo.toml +++ b/bin/core/imag-edit/Cargo.toml @@ -24,6 +24,7 @@ log = "0.4" version = "3" toml = "0.4" toml-query = "0.8" +failure = "0.1" libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-edit/src/main.rs b/bin/core/imag-edit/src/main.rs index 9f8263bb..ab12be67 100644 --- a/bin/core/imag-edit/src/main.rs +++ b/bin/core/imag-edit/src/main.rs @@ -36,6 +36,7 @@ extern crate clap; #[macro_use] extern crate log; +extern crate failure; extern crate libimagentryedit; extern crate libimagerror; @@ -63,7 +64,14 @@ fn main() { let edit_header = rt.cli().is_present("edit-header"); let edit_header_only = rt.cli().is_present("edit-header-only"); - let sids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap(); + let sids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .into_iter(); StoreIdIterator::new(Box::new(sids.into_iter().map(Ok))) .into_get_iter(rt.store()) diff --git a/bin/core/imag-edit/src/ui.rs b/bin/core/imag-edit/src/ui.rs index 3b788251..81eda1ae 100644 --- a/bin/core/imag-edit/src/ui.rs +++ b/bin/core/imag-edit/src/ui.rs @@ -20,11 +20,11 @@ use std::path::PathBuf; use clap::{Arg, ArgMatches, App}; +use failure::Fallible as Result; use libimagstore::storeid::IntoStoreId; use libimagstore::storeid::StoreId; use libimagrt::runtime::IdPathProvider; -use libimagerror::trace::MapErrTrace; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app @@ -54,18 +54,14 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { pub struct PathProvider; impl IdPathProvider for PathProvider { - fn get_ids(matches: &ArgMatches) -> Vec<StoreId> { - matches - .values_of("entry") - .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() + fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + matches.values_of("entry") + .map(|v| v + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::<Result<Vec<_>>>() + ) + .transpose() } } diff --git a/bin/core/imag-gps/src/main.rs b/bin/core/imag-gps/src/main.rs index 0b34605f..ec96721b 100644 --- a/bin/core/imag-gps/src/main.rs +++ b/bin/core/imag-gps/src/main.rs @@ -35,9 +35,8 @@ )] extern crate clap; -#[macro_use] -extern crate log; -extern crate failure; +#[macro_use] extern crate log; +#[macro_use] extern crate failure; extern crate libimagentrygps; #[macro_use] extern crate libimagrt; @@ -52,6 +51,7 @@ use std::str::FromStr; use failure::Error; use failure::err_msg; +use libimagstore::storeid::StoreId; use libimagentrygps::types::*; use libimagentrygps::entry::*; use libimagrt::setup::generate_runtime_setup; @@ -69,8 +69,7 @@ fn main() { "Add GPS coordinates to entries", ui::build_ui); - rt.cli() - .subcommand_name() + rt.cli().subcommand_name() .map(|name| { match name { "add" => add(&rt), @@ -87,6 +86,16 @@ fn main() { }); } +fn rt_get_ids(rt: &Runtime) -> Vec<StoreId> { + rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) +} + fn add(rt: &Runtime) { let c = { let parse = |value: &str| -> (i64, i64, i64) { @@ -124,8 +133,7 @@ fn add(rt: &Runtime) { Coordinates::new(long, lati) }; - rt.ids::<crate::ui::PathProvider>() - .map_err_trace_exit_unwrap() + rt_get_ids(&rt) .into_iter() .for_each(|id| { rt.store() @@ -149,8 +157,7 @@ fn remove(rt: &Runtime) { .unwrap() .is_present("print-removed"); // safed by main() - rt.ids::<crate::ui::PathProvider>() - .map_err_trace_exit_unwrap() + rt_get_ids(&rt) .into_iter() .for_each(|id| { let removed_value = rt @@ -179,8 +186,8 @@ fn remove(rt: &Runtime) { fn get(rt: &Runtime) { let mut stdout = rt.stdout(); - rt.ids::<crate::ui::PathProvider>() - .map_err_trace_exit_unwrap() + + rt_get_ids(&rt) .into_iter() .for_each(|id| { let value = rt diff --git a/bin/core/imag-gps/src/ui.rs b/bin/core/imag-gps/src/ui.rs index 572e1c48..bd7879fe 100644 --- a/bin/core/imag-gps/src/ui.rs +++ b/bin/core/imag-gps/src/ui.rs @@ -20,11 +20,11 @@ use std::path::PathBuf; use clap::{Arg, ArgMatches, App, SubCommand}; +use failure::Fallible as Result; use libimagstore::storeid::IntoStoreId; use libimagstore::storeid::StoreId; use libimagrt::runtime::IdPathProvider; -use libimagerror::trace::MapErrTrace; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app @@ -99,54 +99,23 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { pub struct PathProvider; impl IdPathProvider for PathProvider { - fn get_ids(matches: &ArgMatches) -> Vec<StoreId> { - match matches.subcommand() { - ("add", Some(subm)) => { - subm.values_of("entry") - .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() - }, - - ("remove", Some(subm)) => { - subm.values_of("entry") - .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() - }, - - ("get", Some(subm)) => { - subm.values_of("get-ids") - .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() - }, + fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + subm.values_of(field) + .map(|v| v + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::<Result<Vec<_>>>() + ) + .transpose() + } - (other, _) => { - error!("Not a known command: {}", other); - ::std::process::exit(1) - } + match matches.subcommand() { + ("add", Some(subm)) => get_id_paths("entry", subm), + ("remove", Some(subm)) => get_id_paths("entry", subm), + ("get", Some(subm)) => get_id_paths("get-ids", subm), + (other, _) => Err(format_err!("Not a known command: {}", other)), } } } diff --git a/bin/core/imag-header/src/main.rs b/bin/core/imag-header/src/main.rs index 3e7b01da..10c8805c 100644 --- a/bin/core/imag-header/src/main.rs +++ b/bin/core/imag-header/src/main.rs @@ -79,7 +79,14 @@ fn main() { trace!("list_output_with_ids = {:?}", list_output_with_ids ); trace!("list_output_with_ids_fmt = {:?}", list_output_with_ids_fmt); - let sids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap(); + let sids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .into_iter(); let iter = StoreIdIterator::new(Box::new(sids.into_iter().map(Ok))) .into_get_iter(rt.store()) diff --git a/bin/core/imag-header/src/ui.rs b/bin/core/imag-header/src/ui.rs index f42030eb..f9d1bcbd 100644 --- a/bin/core/imag-header/src/ui.rs +++ b/bin/core/imag-header/src/ui.rs @@ -20,11 +20,11 @@ use std::path::PathBuf; use clap::{Arg, ArgMatches, App, SubCommand}; +use failure::Fallible as Result; 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 @@ -234,11 +234,14 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { pub struct PathProvider; impl IdPathProvider for PathProvider { - fn get_ids(matches: &ArgMatches) -> Vec<StoreId> { + fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> { matches.values_of("id") - .unwrap() - .map(|s| PathBuf::from(s).into_storeid().map_err_trace_exit_unwrap()) - .collect() + .map(|v| v + .into_iter() + .map(PathBuf::from) + .map(|pb| pb.into_storeid()) + .collect::<Result<Vec<_>>>() + ) + .transpose() } } - diff --git a/bin/core/imag-ids/src/main.rs b/bin/core/imag-ids/src/main.rs index dbe271b2..4284b475 100644 --- a/bin/core/imag-ids/src/main.rs +++ b/bin/core/imag-ids/src/main.rs @@ -41,7 +41,7 @@ extern crate filters; #[macro_use] extern crate is_match; extern crate toml; extern crate toml_query; -extern crate failure; +#[macro_use] extern crate failure; #[cfg(test)] extern crate env_logger; @@ -93,7 +93,13 @@ fn main() { let iterator = if rt.ids_from_stdin() { debug!("Fetching IDs from stdin..."); - let ids = rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap(); + let ids = rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }); Box::new(ids.into_iter().map(Ok)) as Box<Iterator<Item = Result<StoreId, _>>> } else { diff --git a/bin/core/imag-ids/src/ui.rs b/bin/core/imag-ids/src/ui.rs index 1a7e15f2..7cfde684 100644 --- a/bin/core/imag-ids/src/ui.rs +++ b/bin/core/imag-ids/src/ui.rs @@ -18,6 +18,7 @@ // use clap::{Arg, ArgMatches, App, SubCommand}; +use failure::Fallible as Result; use libimagstore::storeid::StoreId; use libimagrt::runtime::IdPathProvider; @@ -54,8 +55,7 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { pub struct PathProvider; impl IdPathProvider for PathProvider { - fn get_ids(_matches: &ArgMatches) -> Vec<StoreId> { - error!("imag-ids does not get IDs via CLI, only via stdin if applying a filter!"); - ::std::process::exit(1) + fn get_ids(_matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> { + Err(format_err!("imag-ids does not get IDs via CLI, only via stdin if applying a filter!")) } } diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index 0255f341..3e12f1c0 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -209,8 +209,13 @@ fn remove_linking(rt: &Runtime) { }) .unwrap(); - rt.ids::<crate::ui::PathProvider>() + rt + .ids::<crate::ui::PathProvider>() .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) .into_iter() .for_each(|id| match rt.store().get(id.clone()) { Err(e) => trace_error(&e), @@ -245,19 +250,27 @@ fn remove_linking(rt: &Runtime) { } fn unlink(rt: &Runtime) { - rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap().into_iter().for_each(|id| { - rt.store() - .get(id.clone()) - .map_err_trace_exit_unwrap() - .unwrap_or_else(|| { - warn!("No entry for {}", id); - ::std::process::exit(1) - }) - .unlink(rt.store()) - .map_err_trace_exit_unwrap(); + rt + .ids::<crate::ui::PathProvider>() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .into_iter() + .for_each(|id| { + rt.store() + .get(id.clone()) + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + warn!("No entry for {}", id); + ::std::process::exit(1) + }) + .unlink(rt.store()) + .map_err_trace_exit_unwrap(); - let _ = rt.report_touched(&id).unwrap_or_exit(); - }); + let _ = rt.report_touched(&id).unwrap_or_exit(); + }); } fn list_linkings(rt: &Runtime) { @@ -271,35 +284,24 @@ fn list_linkings(rt: &Runtime) { let mut tab = ::prettytable::Table::new(); tab.set_titles(row!["#", "Link"]); - rt.ids::<crate::ui::PathProvider>().map_err_trace_exit_unwrap().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().enumerate() { - let link = link - .to_str() - .map_warn_err(|e| format!("Failed to convert StoreId to string: {:?}", e)) - .ok(); - - if let Some(link) = link { - if list_plain { - let _ = writeln!(rt.stdout(), "{: <3}: {}", i, link) - .to_exit_code() - .unwrap_or_exit(); - } else { - tab.add_row(row![i, link]); - } - } - } - - if list_externals { - entry.get_external_links(rt.store()) - .map_err_trace_exit_unwrap() - |