diff --git a/bin/core/imag-annotate/Cargo.toml b/bin/core/imag-annotate/Cargo.toml index 6819ea29..25e79c57 100644 --- a/bin/core/imag-annotate/Cargo.toml +++ b/bin/core/imag-annotate/Cargo.toml @@ -26,6 +26,7 @@ log = "0.4.0" url = "1.2" toml = "0.4" toml-query = "0.7" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-annotate/src/main.rs b/bin/core/imag-annotate/src/main.rs index ddeecf90..639488ea 100644 --- a/bin/core/imag-annotate/src/main.rs +++ b/bin/core/imag-annotate/src/main.rs @@ -35,6 +35,7 @@ extern crate clap; #[macro_use] extern crate log; +extern crate failure; extern crate libimagentryannotation; extern crate libimagentryedit; @@ -46,9 +47,11 @@ extern crate libimagutil; use std::io::Write; use std::path::PathBuf; +use failure::Error; +use failure::err_msg; + use libimagentryannotation::annotateable::*; use libimagentryannotation::annotation_fetcher::*; -use libimagentryannotation::error::AnnotationError as AE; use libimagentryedit::edit::*; use libimagerror::trace::MapErrTrace; use libimagerror::exit::ExitUnwrap; @@ -97,7 +100,7 @@ fn add(rt: &Runtime) { let _ = rt.store() .get(entry_name) .map_err_trace_exit_unwrap(1) - .ok_or(AE::from("Entry does not exist".to_owned())) + .ok_or_else(|| Error::from(err_msg("Entry does not exist".to_owned()))) .map_err_trace_exit_unwrap(1) .annotate(rt.store(), annotation_name) .map_err_trace_exit_unwrap(1) @@ -114,7 +117,7 @@ fn remove(rt: &Runtime) { let mut entry = rt.store() .get(PathBuf::from(entry_name).into_storeid().map_err_trace_exit_unwrap(1)) .map_err_trace_exit_unwrap(1) - .ok_or(AE::from("Entry does not exist".to_owned())) + .ok_or_else(|| Error::from(err_msg("Entry does not exist".to_owned()))) .map_err_trace_exit_unwrap(1); let annotation = entry @@ -148,7 +151,7 @@ fn list(rt: &Runtime) { .store() .get(pb.into_storeid().map_err_trace_exit_unwrap(1)) .map_err_trace_exit_unwrap(1) - .ok_or(AE::from("Entry does not exist".to_owned())) + .ok_or_else(|| Error::from(err_msg("Entry does not exist"))) .map_err_trace_exit_unwrap(1) .annotations(rt.store()) .map_err_trace_exit_unwrap(1) diff --git a/bin/core/imag-category/Cargo.toml b/bin/core/imag-category/Cargo.toml index 509db077..d7d2f425 100644 --- a/bin/core/imag-category/Cargo.toml +++ b/bin/core/imag-category/Cargo.toml @@ -24,7 +24,7 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-diagnostics/Cargo.toml b/bin/core/imag-diagnostics/Cargo.toml index 58658242..20fce9ee 100644 --- a/bin/core/imag-diagnostics/Cargo.toml +++ b/bin/core/imag-diagnostics/Cargo.toml @@ -18,8 +18,9 @@ build = "../../../build.rs" [dependencies] log = "0.4" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } indicatif = "0.9" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-diagnostics/src/main.rs b/bin/core/imag-diagnostics/src/main.rs index d8d8482b..5c592db0 100644 --- a/bin/core/imag-diagnostics/src/main.rs +++ b/bin/core/imag-diagnostics/src/main.rs @@ -36,6 +36,7 @@ extern crate clap; extern crate toml; extern crate toml_query; extern crate indicatif; +extern crate failure; #[macro_use] extern crate log; #[macro_use] extern crate libimagrt; @@ -52,12 +53,14 @@ use libimagerror::io::ToExitCode; use libimagerror::exit::ExitUnwrap; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreId; -use libimagstore::error::StoreError as Error; use libimagentrylink::internal::*; use toml::Value; use toml_query::read::TomlValueReadExt; use indicatif::{ProgressBar, ProgressStyle}; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; use std::collections::BTreeMap; @@ -76,7 +79,7 @@ struct Diagnostic { impl Diagnostic { - fn for_entry<'a>(entry: &FileLockEntry<'a>) -> Result { + fn for_entry<'a>(entry: &FileLockEntry<'a>) -> Result { Ok(Diagnostic { id: entry.get_location().clone(), entry_store_version: entry @@ -142,7 +145,7 @@ fn main() { .into_get_iter() .map(|e| { e.map_err_trace_exit_unwrap(1) - .ok_or(Error::from("Unable to get entry".to_owned())) + .ok_or_else(|| Error::from(err_msg("Unable to get entry".to_owned()))) .map_err_trace_exit_unwrap(1) }) .map(|e| { @@ -163,7 +166,7 @@ fn main() { diag }) - .collect::, _>>() + .collect::>>() .map_err_trace_exit_unwrap(1); spinner.finish(); @@ -265,6 +268,7 @@ fn main() { fn get_config(rt: &Runtime, s: &'static str) -> Option { rt.config().and_then(|cfg| { cfg.read(s) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) .map(|opt| match opt { &Value::String(ref s) => s.to_owned(), diff --git a/bin/core/imag-gps/Cargo.toml b/bin/core/imag-gps/Cargo.toml index 85822c6d..52c7d31f 100644 --- a/bin/core/imag-gps/Cargo.toml +++ b/bin/core/imag-gps/Cargo.toml @@ -26,6 +26,7 @@ log = "0.4.0" url = "1.2" toml = "0.4" toml-query = "0.7" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-gps/src/main.rs b/bin/core/imag-gps/src/main.rs index a4415594..abf121ac 100644 --- a/bin/core/imag-gps/src/main.rs +++ b/bin/core/imag-gps/src/main.rs @@ -35,6 +35,7 @@ extern crate clap; #[macro_use] extern crate log; +extern crate failure; extern crate libimagentrygps; #[macro_use] extern crate libimagrt; @@ -47,8 +48,9 @@ use std::process::exit; use std::path::PathBuf; use std::str::FromStr; -use libimagentrygps::error::GPSError as GE; -use libimagentrygps::error::GPSErrorKind as GEK; +use failure::Error; +use failure::err_msg; + use libimagentrygps::types::*; use libimagentrygps::entry::*; use libimagrt::setup::generate_runtime_setup; @@ -100,7 +102,7 @@ fn add(rt: &Runtime) { .map(|v| {debug!("Parsing = {}", v); v}) .map(FromStr::from_str) .map(|elem| { - elem.or_else(|_| Err(GE::from(GEK::NumberConversionError))) + elem.or_else(|_| Err(Error::from(err_msg("Error while converting number")))) .map_err_trace_exit_unwrap(1) }) .collect::>(); diff --git a/bin/core/imag-ids/Cargo.toml b/bin/core/imag-ids/Cargo.toml index da335333..84222b38 100644 --- a/bin/core/imag-ids/Cargo.toml +++ b/bin/core/imag-ids/Cargo.toml @@ -26,8 +26,9 @@ filters = "0.3" nom = "3.2" log = "0.4" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } is-match = "0.1" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-ids/src/id_filters.rs b/bin/core/imag-ids/src/id_filters.rs index 537e23a0..e595b346 100644 --- a/bin/core/imag-ids/src/id_filters.rs +++ b/bin/core/imag-ids/src/id_filters.rs @@ -51,6 +51,7 @@ pub mod header_filter_lang { use nom::digit; use nom::multispace; + use failure::Error; use libimagstore::store::Entry; use libimagerror::trace::MapErrTrace; @@ -403,6 +404,7 @@ pub mod header_filter_lang { entry .get_header() .read(selector_str) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) .map(|value| { let comp = Comparator(&self.compare_operator, &self.compare_value); diff --git a/bin/core/imag-ids/src/main.rs b/bin/core/imag-ids/src/main.rs index f69fd891..63998ce2 100644 --- a/bin/core/imag-ids/src/main.rs +++ b/bin/core/imag-ids/src/main.rs @@ -39,6 +39,7 @@ extern crate filters; #[macro_use] extern crate is_match; extern crate toml; extern crate toml_query; +extern crate failure; #[cfg(test)] extern crate env_logger; @@ -68,7 +69,7 @@ fn main() { let version = make_imag_version!(); let rt = generate_runtime_setup("imag-ids", &version, - "Print all ids, optionally filtered with a user-defined filter", + "print all ids", build_ui); let print_storepath = rt.cli().is_present("print-storepath"); diff --git a/bin/core/imag-link/Cargo.toml b/bin/core/imag-link/Cargo.toml index dd503bef..20db392c 100644 --- a/bin/core/imag-link/Cargo.toml +++ b/bin/core/imag-link/Cargo.toml @@ -25,8 +25,9 @@ maintenance = { status = "actively-developed" } log = "0.4.0" url = "1.5" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } prettytable-rs = "0.8" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index 5a177308..e0b55149 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -35,6 +35,7 @@ #[macro_use] extern crate log; extern crate clap; extern crate url; +extern crate failure; #[macro_use] extern crate prettytable; #[cfg(test)] extern crate toml; #[cfg(test)] extern crate toml_query; @@ -55,22 +56,24 @@ extern crate libimagutil; use std::io::Write; use std::path::PathBuf; +use failure::Error; +use failure::err_msg; + use libimagentrylink::external::ExternalLinker; use libimagentrylink::internal::InternalLinker; use libimagentrylink::internal::store_check::StoreLinkConsistentExt; -use libimagentrylink::error::LinkError as LE; use libimagerror::trace::{MapErrTrace, trace_error}; use libimagerror::exit::ExitUnwrap; use libimagerror::io::ToExitCode; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; -use libimagstore::error::StoreError; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreId; use libimagutil::warn_exit::warn_exit; use libimagutil::warn_result::*; use url::Url; +use failure::Fallible as Result; mod ui; @@ -80,7 +83,7 @@ fn main() { let version = make_imag_version!(); let rt = generate_runtime_setup("imag-link", &version, - "Add/Remove links between entries", + "Link entries", build_ui); if rt.cli().is_present("check-consistency") { let exit_code = match rt.store().check_link_consistency() { @@ -119,11 +122,11 @@ fn main() { warn_exit("No commandline call", 1) } }) - .ok_or(LE::from("No commandline call".to_owned())) + .ok_or_else(|| Error::from(err_msg("No commandline call".to_owned()))) .map_err_trace_exit_unwrap(1); } -fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result>, StoreError> { +fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result>> { use libimagstore::storeid::StoreId; debug!("Getting: {:?}", name); @@ -336,11 +339,12 @@ mod tests { use toml::value::Value; use toml_query::read::TomlValueReadExt; - use toml_query::error::Result as TomlQueryResult; + use failure::Fallible as Result; + use failure::Error; use libimagrt::runtime::Runtime; use libimagstore::storeid::StoreId; - use libimagstore::store::{Result as StoreResult, FileLockEntry, Entry}; + use libimagstore::store::{FileLockEntry, Entry}; fn setup_logging() { let _ = ::env_logger::try_init(); @@ -355,7 +359,7 @@ mod tests { use self::mock::generate_test_runtime; use self::mock::reset_test_runtime; - fn create_test_default_entry<'a, S: AsRef>(rt: &'a Runtime, name: S) -> StoreResult { + fn create_test_default_entry<'a, S: AsRef>(rt: &'a Runtime, name: S) -> Result { let mut path = PathBuf::new(); path.set_file_name(name); @@ -376,11 +380,10 @@ mod tests { Ok(id) } - fn get_entry_links<'a>(entry: &'a FileLockEntry<'a>) -> TomlQueryResult<&'a Value> { - match entry.get_header().read(&"links.internal".to_owned()) { - Err(e) => Err(e), - Ok(Some(v)) => Ok(v), - Ok(None) => panic!("Didn't find 'links' in {:?}", entry), + fn get_entry_links<'a>(entry: &'a FileLockEntry<'a>) -> Result<&'a Value> { + match entry.get_header().read(&"links.internal".to_owned()).map_err(Error::from)? { + Some(v) => Ok(v), + None => panic!("Didn't find 'links' in {:?}", entry), } } @@ -394,7 +397,7 @@ mod tests { #[test] fn test_link_modificates() { setup_logging(); - let rt = generate_test_runtime(vec!["test1", "test2"]) + let rt = generate_test_runtime(vec!["internal", "test1", "test2"]) .unwrap(); debug!("Runtime created"); @@ -423,7 +426,7 @@ mod tests { #[test] fn test_linking_links() { setup_logging(); - let rt = generate_test_runtime(vec!["test1", "test2"]) + let rt = generate_test_runtime(vec!["internal", "test1", "test2"]) .unwrap(); debug!("Runtime created"); @@ -452,7 +455,7 @@ mod tests { #[test] fn test_multilinking() { setup_logging(); - let rt = generate_test_runtime(vec!["test1", "test2"]) + let rt = generate_test_runtime(vec!["internal", "test1", "test2"]) .unwrap(); debug!("Runtime created"); @@ -482,7 +485,7 @@ mod tests { #[test] fn test_linking_more_than_two() { setup_logging(); - let rt = generate_test_runtime(vec!["test1", "test2", "test3"]) + let rt = generate_test_runtime(vec!["internal", "test1", "test2", "test3"]) .unwrap(); debug!("Runtime created"); @@ -519,7 +522,7 @@ mod tests { #[test] fn test_linking_links_unlinking_removes_links() { setup_logging(); - let rt = generate_test_runtime(vec!["test1", "test2"]) + let rt = generate_test_runtime(vec!["internal", "test1", "test2"]) .unwrap(); debug!("Runtime created"); @@ -555,7 +558,7 @@ mod tests { #[test] fn test_linking_and_unlinking_more_than_two() { setup_logging(); - let rt = generate_test_runtime(vec!["test1", "test2", "test3"]) + let rt = generate_test_runtime(vec!["internal", "test1", "test2", "test3"]) .unwrap(); debug!("Runtime created"); diff --git a/bin/core/imag-mv/src/main.rs b/bin/core/imag-mv/src/main.rs index aeac022b..3dfb9798 100644 --- a/bin/core/imag-mv/src/main.rs +++ b/bin/core/imag-mv/src/main.rs @@ -53,7 +53,6 @@ use libimagerror::iter::TraceIterator; use libimagstore::storeid::StoreId; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; -use libimagstore::error::StoreError; use libimagentrylink::internal::InternalLinker; use libimagstore::iter::get::StoreIdGetIteratorExtension; @@ -93,7 +92,7 @@ fn main() { }) .get_internal_links() .map_err_trace_exit_unwrap(1) - .map(|link| Ok(link.get_store_id().clone()) as Result<_, StoreError>) + .map(|link| Ok(link.get_store_id().clone()) as Result<_, _>) .into_get_iter(rt.store()) .trace_unwrap_exit(1) .map(|e| { diff --git a/bin/core/imag-store/Cargo.toml b/bin/core/imag-store/Cargo.toml index 9bc96a41..63731f56 100644 --- a/bin/core/imag-store/Cargo.toml +++ b/bin/core/imag-store/Cargo.toml @@ -24,7 +24,7 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -error-chain = "0.12" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore", features = ["verify"] } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-store/src/create.rs b/bin/core/imag-store/src/create.rs index f7365b8c..6ee5ecfe 100644 --- a/bin/core/imag-store/src/create.rs +++ b/bin/core/imag-store/src/create.rs @@ -20,12 +20,13 @@ use std::path::PathBuf; use std::io::stdin; use std::fs::OpenOptions; -use std::result::Result as RResult; use std::io::Read; use std::ops::DerefMut; use clap::ArgMatches; use toml::Value; +use failure::Fallible as Result; +use failure::err_msg; use libimagrt::runtime::Runtime; use libimagstore::store::Entry; @@ -33,13 +34,8 @@ use libimagstore::storeid::StoreId; use libimagerror::trace::MapErrTrace; use libimagutil::debug_result::*; -use error::StoreError; -use error::StoreErrorKind; -use error::ResultExt; use util::build_toml_header; -type Result = RResult; - pub fn create(rt: &Runtime) { let scmd = rt.cli().subcommand_matches("create").unwrap(); debug!("Found 'create' subcommand..."); @@ -95,13 +91,9 @@ fn create_from_cli_spec(rt: &Runtime, matches: &ArgMatches, path: &StoreId) -> R fn create_from_source(rt: &Runtime, matches: &ArgMatches, path: &StoreId) -> Result<()> { let content = matches .value_of("from-raw") - .ok_or(StoreError::from_kind(StoreErrorKind::NoCommandlineCall)) - .map(string_from_raw_src); + .ok_or_else(|| err_msg("No Commandline call")) + .map(string_from_raw_src)?; - if content.is_err() { - return content.map(|_| ()); - } - let content = content.unwrap(); debug!("Content with len = {}", content.len()); Entry::from_str(path.clone(), &content[..]) @@ -118,7 +110,6 @@ fn create_from_source(rt: &Runtime, matches: &ArgMatches, path: &StoreId) -> Res r }) .map_dbg_err(|e| format!("Error storing entry: {:?}", e)) - .chain_err(|| StoreErrorKind::BackendError) } fn create_with_content_and_header(rt: &Runtime, @@ -142,7 +133,6 @@ fn create_with_content_and_header(rt: &Runtime, debug!("New header set"); } }) - .chain_err(|| StoreErrorKind::BackendError) } fn string_from_raw_src(raw_src: &str) -> String { diff --git a/bin/core/imag-store/src/error.rs b/bin/core/imag-store/src/error.rs deleted file mode 100644 index be517759..00000000 --- a/bin/core/imag-store/src/error.rs +++ /dev/null @@ -1,38 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - StoreError, StoreErrorKind, ResultExt, Result; - } - - errors { - BackendError { - description("Backend Error") - display("Backend Error") - } - - NoCommandlineCall { - description("No commandline call") - display("No commandline call") - } - - } -} - diff --git a/bin/core/imag-store/src/main.rs b/bin/core/imag-store/src/main.rs index 6a907965..5328c3ac 100644 --- a/bin/core/imag-store/src/main.rs +++ b/bin/core/imag-store/src/main.rs @@ -36,7 +36,7 @@ extern crate clap; #[macro_use] extern crate log; extern crate toml; #[cfg(test)] extern crate toml_query; -#[macro_use] extern crate error_chain; +extern crate failure; #[macro_use] extern crate libimagrt; extern crate libimagstore; @@ -54,7 +54,6 @@ use libimagerror::trace::MapErrTrace; mod create; mod delete; -mod error; mod get; mod retrieve; mod ui; diff --git a/bin/core/imag-tag/Cargo.toml b/bin/core/imag-tag/Cargo.toml index fb30659e..e591586f 100644 --- a/bin/core/imag-tag/Cargo.toml +++ b/bin/core/imag-tag/Cargo.toml @@ -37,8 +37,9 @@ default-features = false features = ["color", "suggestions", "wrap_help"] [dev-dependencies] -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } env_logger = "0.5" +failure = "0.1" [dev-dependencies.libimagutil] version = "0.9.0" diff --git a/bin/core/imag-tag/src/main.rs b/bin/core/imag-tag/src/main.rs index 01387336..25fb6707 100644 --- a/bin/core/imag-tag/src/main.rs +++ b/bin/core/imag-tag/src/main.rs @@ -36,6 +36,7 @@ extern crate clap; #[macro_use] extern crate log; #[cfg(test)] extern crate toml; +#[cfg(test)] extern crate failure; extern crate libimagstore; #[macro_use] extern crate libimagrt; @@ -80,7 +81,7 @@ fn main() { let version = make_imag_version!(); let rt = generate_runtime_setup("imag-tag", &version, - "Add and remove tags for entries", + "Direct interface to the store. Use with great care!", build_ui); let ids : Vec = rt @@ -269,11 +270,12 @@ mod tests { use toml::value::Value; use toml_query::read::TomlValueReadExt; - use toml_query::error::Result as TomlQueryResult; + use failure::Fallible as Result; + use failure::Error; use libimagrt::runtime::Runtime; use libimagstore::storeid::StoreId; - use libimagstore::store::{Result as StoreResult, FileLockEntry, Entry}; + use libimagstore::store::{FileLockEntry, Entry}; use super::*; @@ -285,7 +287,7 @@ mod tests { } use self::mock::generate_test_runtime; - fn create_test_default_entry<'a, S: AsRef>(rt: &'a Runtime, name: S) -> StoreResult { + fn create_test_default_entry<'a, S: AsRef>(rt: &'a Runtime, name: S) -> Result { let mut path = PathBuf::new(); path.set_file_name(name); @@ -300,8 +302,8 @@ mod tests { Ok(id) } - fn get_entry_tags<'a>(entry: &'a FileLockEntry<'a>) -> TomlQueryResult> { - entry.get_header().read(&"tag.values".to_owned()) + fn get_entry_tags<'a>(entry: &'a FileLockEntry<'a>) -> Result> { + entry.get_header().read(&"tag.values".to_owned()).map_err(Error::from) } fn tags_toml_value<'a, I: IntoIterator>(tags: I) -> Value { diff --git a/bin/core/imag-view/Cargo.toml b/bin/core/imag-view/Cargo.toml index 93d10cf7..75df7a1f 100644 --- a/bin/core/imag-view/Cargo.toml +++ b/bin/core/imag-view/Cargo.toml @@ -24,9 +24,10 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } handlebars = "1.0" tempfile = "3" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-view/src/main.rs b/bin/core/imag-view/src/main.rs index bef7e2bc..43ed4b23 100644 --- a/bin/core/imag-view/src/main.rs +++ b/bin/core/imag-view/src/main.rs @@ -38,6 +38,7 @@ extern crate handlebars; extern crate tempfile; extern crate toml; extern crate toml_query; +extern crate failure; extern crate libimagentryview; extern crate libimagerror; @@ -55,10 +56,11 @@ use std::process::exit; use handlebars::Handlebars; use toml_query::read::TomlValueReadTypeExt; +use failure::Error; +use failure::err_msg; use libimagrt::setup::generate_runtime_setup; use libimagrt::runtime::Runtime; -use libimagerror::str::ErrFromStr; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagerror::io::ToExitCode; @@ -66,10 +68,8 @@ use libimagerror::exit::ExitUnwrap; use libimagentryview::builtin::stdout::StdoutViewer; use libimagentryview::builtin::md::MarkdownViewer; use libimagentryview::viewer::Viewer; -use libimagentryview::error::ViewError as VE; use libimagstore::storeid::IntoStoreId; use libimagstore::storeid::StoreIdIterator; -use libimagstore::error::StoreError; use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagstore::store::FileLockEntry; @@ -92,8 +92,7 @@ fn main() { .into_get_iter(rt.store()) .trace_unwrap_exit(1) .map(|e| { - e.ok_or_else(|| String::from("Entry not found")) - .map_err(StoreError::from) + e.ok_or_else(|| err_msg("Entry not found")) .map_err_trace_exit_unwrap(1) }) .map(|entry| create_tempfile_for(&entry, view_header, hide_content)) @@ -103,18 +102,19 @@ fn main() { let viewer = rt .cli() .value_of("in") - .ok_or_else::(|| "No viewer given".to_owned().into()) + .ok_or_else(|| Error::from(err_msg("No viewer given"))) .map_err_trace_exit_unwrap(1); let config = rt .config() - .ok_or_else::(|| "No configuration, cannot continue".to_owned().into()) + .ok_or_else(|| Error::from(err_msg("No configuration, cannot continue"))) .map_err_trace_exit_unwrap(1); let query = format!("view.viewers.{}", viewer); let viewer_template = config .read_string(&query) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) .unwrap_or_else(|| { error!("Cannot find '{}' in config", query); @@ -126,8 +126,7 @@ fn main() { let _ = handlebars .register_template_string("template", viewer_template) - .err_from_str() - .map_err(VE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); let mut data = BTreeMap::new(); @@ -142,13 +141,12 @@ fn main() { let call = handlebars .render("template", &data) - .err_from_str() - .map_err(VE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); let mut elems = call.split_whitespace(); let command_string = elems .next() - .ok_or::("No command".to_owned().into()) + .ok_or_else(|| Error::from(err_msg("No command"))) .map_err_trace_exit_unwrap(1); let mut cmd = Command::new(command_string); @@ -163,8 +161,7 @@ fn main() { if !command .status() - .err_from_str() - .map_err(VE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) .success() { @@ -177,8 +174,7 @@ fn main() { .into_get_iter(rt.store()) .map(|e| { e.map_err_trace_exit_unwrap(1) - .ok_or_else(|| String::from("Entry not found")) - .map_err(StoreError::from) + .ok_or_else(|| err_msg("Entry not found")) .map_err_trace_exit_unwrap(1) }); @@ -282,25 +278,21 @@ fn create_tempfile_for<'a>(entry: &FileLockEntry<'a>, view_header: bool, hide_co -> (tempfile::NamedTempFile, String) { let mut tmpfile = tempfile::NamedTempFile::new() - .err_from_str() - .map_err(VE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); if view_header { let hdr = toml::ser::to_string_pretty(entry.get_header()) - .err_from_str() - .map_err(VE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); let _ = tmpfile.write(format!("---\n{}---\n", hdr).as_bytes()) - .err_from_str() - .map_err(VE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); } if !hide_content { let _ = tmpfile.write(entry.get_content().as_bytes()) - .err_from_str() - .map_err(VE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); } @@ -308,7 +300,7 @@ fn create_tempfile_for<'a>(entry: &FileLockEntry<'a>, view_header: bool, hide_co .path() .to_str() .map(String::from) - .ok_or::("Cannot build path".to_owned().into()) + .ok_or_else(|| Error::from(err_msg("Cannot build path"))) .map_err_trace_exit_unwrap(1); (tmpfile, file_path) diff --git a/bin/core/imag/Cargo.toml b/bin/core/imag/Cargo.toml index 051792fe..77472b8c 100644 --- a/bin/core/imag/Cargo.toml +++ b/bin/core/imag/Cargo.toml @@ -32,7 +32,6 @@ walkdir = "2" log = "0.4.0" toml = "0.4" toml-query = "0.7" -is-match = "0.1" libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/bin/core/imag/src/main.rs b/bin/core/imag/src/main.rs index 9b8267ca..37279dd0 100644 --- a/bin/core/imag/src/main.rs +++ b/bin/core/imag/src/main.rs @@ -37,7 +37,6 @@ extern crate clap; extern crate walkdir; extern crate toml; extern crate toml_query; -#[macro_use] extern crate is_match; #[macro_use] extern crate libimagrt; extern crate libimagerror; @@ -56,7 +55,6 @@ use clap::{Arg, ArgMatches, AppSettings, SubCommand}; use toml::Value; use toml_query::read::TomlValueReadExt; -use libimagrt::error::RuntimeErrorKind; use libimagrt::runtime::Runtime; use libimagrt::spec::CliSpec; use libimagerror::io::ToExitCode; @@ -91,7 +89,7 @@ fn help_text(cmds: Vec) -> String { Call a command with 'imag ' Each command can be called with "--help" to get the respective helptext. - Please visit https://git.imag-pim.org/imag to view the source code, + Please visit https://github.com/matthiasbeyer/imag to view the source code, follow the development of imag or maybe even contribute to imag. imag is free software. It is released under the terms of LGPLv2.1 @@ -190,17 +188,11 @@ fn main() { .value_of(Runtime::arg_config_name()) .map_or_else(|| rtp.clone(), PathBuf::from); debug!("Config path = {:?}", configpath); - let config = match ::libimagrt::configuration::fetch_config(&configpath) { - Ok(c) => Some(c), - Err(e) => if !is_match!(e.kind(), &RuntimeErrorKind::ConfigNoConfigFileFound) { - trace_error(&e); - ::std::process::exit(1) - } else { - println!("No config file found."); - println!("Continuing without configuration file"); - None - }, - }; + let config = ::libimagrt::configuration::fetch_config(&configpath) + .unwrap_or_else(|e| { + trace_error(&e); + exit(1) + }); debug!("matches: {:?}", matches); diff --git a/bin/domain/imag-bookmark/Cargo.toml b/bin/domain/imag-bookmark/Cargo.toml index ecc0a252..403419bd 100644 --- a/bin/domain/imag-bookmark/Cargo.toml +++ b/bin/domain/imag-bookmark/Cargo.toml @@ -24,7 +24,8 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/bin/domain/imag-bookmark/src/main.rs b/bin/domain/imag-bookmark/src/main.rs index 2741e898..1a9c1893 100644 --- a/bin/domain/imag-bookmark/src/main.rs +++ b/bin/domain/imag-bookmark/src/main.rs @@ -36,6 +36,7 @@ extern crate clap; #[macro_use] extern crate log; extern crate toml; extern crate toml_query; +#[macro_use] extern crate failure; extern crate libimagbookmark; #[macro_use] extern crate libimagrt; @@ -46,12 +47,12 @@ use std::io::Write; use std::process::exit; use toml_query::read::TomlValueReadTypeExt; +use failure::Error; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagbookmark::collection::BookmarkCollection; use libimagbookmark::collection::BookmarkCollectionStore; -use libimagbookmark::error::BookmarkError as BE; use libimagbookmark::link::Link as BookmarkLink; use libimagerror::trace::{MapErrTrace, trace_error}; use libimagerror::io::ToExitCode; @@ -94,7 +95,7 @@ fn add(rt: &Runtime) { let mut collection = BookmarkCollectionStore::get(rt.store(), &coll) .map_err_trace_exit_unwrap(1) - .ok_or(BE::from(format!("No bookmark collection '{}' found", coll))) + .ok_or_else(|| format_err!("No bookmark collection '{}' found", coll)) .map_err_trace_exit_unwrap(1); for url in scmd.values_of("urls").unwrap() { // unwrap saved by clap @@ -135,7 +136,7 @@ fn list(rt: &Runtime) { let collection = BookmarkCollectionStore::get(rt.store(), &coll) .map_err_trace_exit_unwrap(1) - .ok_or(BE::from(format!("No bookmark collection '{}' found", coll))) + .ok_or_else(|| format_err!("No bookmark collection '{}' found", coll)) .map_err_trace_exit_unwrap(1); let links = collection.links(rt.store()).map_err_trace_exit_unwrap(1); @@ -157,7 +158,7 @@ fn remove(rt: &Runtime) { let mut collection = BookmarkCollectionStore::get(rt.store(), &coll) .map_err_trace_exit_unwrap(1) - .ok_or(BE::from(format!("No bookmark collection '{}' found", coll))) + .ok_or_else(|| format_err!("No bookmark collection '{}' found", coll)) .map_err_trace_exit_unwrap(1); for url in scmd.values_of("urls").unwrap() { // enforced by clap @@ -182,6 +183,7 @@ fn get_collection_name(rt: &Runtime, rt.config() .map(|cfg| { cfg.read_string("bookmark.default_collection") + .map_err(Error::from) .map_err_trace_exit_unwrap(1) .ok_or_else(|| { error!("Missing config: 'bookmark.default_collection'. Set or use commandline to specify."); diff --git a/bin/domain/imag-contact/Cargo.toml b/bin/domain/imag-contact/Cargo.toml index 64db919a..11e8aafd 100644 --- a/bin/domain/imag-contact/Cargo.toml +++ b/bin/domain/imag-contact/Cargo.toml @@ -24,12 +24,13 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -toml-query = "0.7" -vobject = { git = "https://github.com/matthiasbeyer/rust-vobject", branch = "update-errorchain" } +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +vobject = { git = "https://github.com/matthiasbeyer/rust-vobject", branch = "master" } handlebars = "1.0" walkdir = "2" uuid = { version = "0.7", features = ["v4"] } serde_json = "1" +failure = "0.1" libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } diff --git a/bin/domain/imag-contact/src/create.rs b/bin/domain/imag-contact/src/create.rs index 02e2ec11..a99ef869 100644 --- a/bin/domain/imag-contact/src/create.rs +++ b/bin/domain/imag-contact/src/create.rs @@ -44,11 +44,10 @@ use vobject::write_component; use toml_query::read::TomlValueReadExt; use toml::Value; use uuid::Uuid; +use failure::Error; use libimagcontact::store::ContactStore; -use libimagcontact::error::ContactError as CE; use libimagrt::runtime::Runtime; -use libimagerror::str::ErrFromStr; use libimagerror::trace::MapErrTrace; use libimagerror::trace::trace_error; use libimagutil::warn_result::WarnResult; @@ -126,8 +125,7 @@ pub fn create(rt: &Runtime) { .create_new(true) .open(fl.clone()) .map_warn_err_str("Cannot create/open destination File. Stopping.") - .err_from_str() - .map_err(CE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); let uuid_string = uuid @@ -161,8 +159,7 @@ pub fn create(rt: &Runtime) { match ::toml::de::from_str(&template) .map(|toml| parse_toml_into_vcard(toml, uuid.clone())) - .err_from_str() - .map_err(CE::from) + .map_err(Error::from) { Err(e) => { error!("Error parsing template"); @@ -183,7 +180,7 @@ pub fn create(rt: &Runtime) { let vcard_string = write_component(&vcard); let _ = dest .write_all(&vcard_string.as_bytes()) - .map_err(CE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); break; @@ -244,7 +241,7 @@ fn parse_toml_into_vcard(toml: Value, uuid: String) -> Option { { // parse nicknames debug!("Parsing nicknames"); - match toml.read("nickname").map_err_trace_exit_unwrap(1) { + match toml.read("nickname").map_err(Error::from).map_err_trace_exit_unwrap(1) { Some(&Value::Array(ref ary)) => { for (i, element) in ary.iter().enumerate() { let nicktype = match read_str_from_toml(element, "type", false) { @@ -306,7 +303,7 @@ fn parse_toml_into_vcard(toml: Value, uuid: String) -> Option { { // parse phone debug!("Parse phone"); - match toml.read("person.phone").map_err_trace_exit_unwrap(1) { + match toml.read("person.phone").map_err(Error::from).map_err_trace_exit_unwrap(1) { Some(&Value::Array(ref ary)) => { for (i, element) in ary.iter().enumerate() { let phonetype = match read_str_from_toml(element, "type", false) { @@ -344,7 +341,7 @@ fn parse_toml_into_vcard(toml: Value, uuid: String) -> Option { { // parse address debug!("Parsing address"); - match toml.read("addresses").map_err_trace_exit_unwrap(1) { + match toml.read("addresses").map_err(Error::from).map_err_trace_exit_unwrap(1) { Some(&Value::Array(ref ary)) => { for (i, element) in ary.iter().enumerate() { let adrtype = match read_str_from_toml(element, "type", false) { @@ -391,7 +388,7 @@ fn parse_toml_into_vcard(toml: Value, uuid: String) -> Option { { // parse email debug!("Parsing email"); - match toml.read("person.email").map_err_trace_exit_unwrap(1) { + match toml.read("person.email").map_err(Error::from).map_err_trace_exit_unwrap(1) { Some(&Value::Array(ref ary)) => { for (i, element) in ary.iter().enumerate() { let mailtype = match read_str_from_toml(element, "type", false) { @@ -456,7 +453,7 @@ fn parse_toml_into_vcard(toml: Value, uuid: String) -> Option { } fn read_strary_from_toml(toml: &Value, path: &'static str) -> Option> { - match toml.read(path).map_warn_err_str(&format!("Failed to read value at '{}'", path)) { + match toml.read(path).map_err(Error::from).map_warn_err_str(&format!("Failed to read value at '{}'", path)) { Ok(Some(&Value::Array(ref vec))) => { let mut v = Vec::new(); for elem in vec { @@ -486,6 +483,7 @@ fn read_strary_from_toml(toml: &Value, path: &'static str) -> Option fn read_str_from_toml(toml: &Value, path: &'static str, must_be_there: bool) -> Option { let v = toml.read(path) + .map_err(Error::from) .map_warn_err_str(&format!("Failed to read value at '{}'", path)); match v { diff --git a/bin/domain/imag-contact/src/main.rs b/bin/domain/imag-contact/src/main.rs index a89a6b06..05599965 100644 --- a/bin/domain/imag-contact/src/main.rs +++ b/bin/domain/imag-contact/src/main.rs @@ -41,6 +41,7 @@ extern crate handlebars; extern crate walkdir; extern crate uuid; extern crate serde_json; +extern crate failure; extern crate libimagcontact; extern crate libimagstore; @@ -58,16 +59,16 @@ use handlebars::Handlebars; use clap::ArgMatches; use toml_query::read::TomlValueReadTypeExt; use walkdir::WalkDir; +use failure::Error; +use failure::err_msg; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; -use libimagerror::str::ErrFromStr; use libimagerror::trace::MapErrTrace; use libimagerror::io::ToExitCode; use libimagerror::exit::ExitUnwrap; use libimagerror::iter::TraceIterator; use libimagcontact::store::ContactStore; -use libimagcontact::error::ContactError as CE; use libimagcontact::contact::Contact; use libimagcontact::deser::DeserVcard; use libimagstore::iter::get::StoreIdGetIteratorExtension; @@ -121,7 +122,7 @@ fn list(rt: &Runtime) { .map(|fle| { let fle = fle .map_err_trace_exit_unwrap(1) - .ok_or_else(|| CE::from("StoreId not found".to_owned())) + .ok_or_else(|| Error::from(err_msg("StoreId not found".to_owned()))) .map_err_trace_exit_unwrap(1); fle.deser().map_err_trace_exit_unwrap(1) @@ -144,8 +145,7 @@ fn list(rt: &Runtime) { let data = build_data_object_for_handlebars(i, &deservcard); list_format.render("format", &data) - .err_from_str() - .map_err(CE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) }) @@ -175,8 +175,7 @@ fn import(rt: &Runtime) { } else if path.is_dir() { for entry in WalkDir::new(path).min_depth(1).into_iter() { let entry = entry - .err_from_str() - .map_err(CE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); if entry.file_type().is_file() { let pb = PathBuf::from(entry.path()); @@ -233,8 +232,7 @@ fn show(rt: &Runtime) { let s = show_format .render("format", &data) - .err_from_str() - .map_err(CE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); let _ = writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit(); }); @@ -324,8 +322,7 @@ fn find(rt: &Runtime) { let data = build_data_object_for_handlebars(i, &card); let s = fmt .render("format", &data) - .err_from_str() - .map_err(CE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); let _ = writeln!(rt.stdout(), "{}", s) @@ -341,19 +338,19 @@ fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd: .map(String::from) .unwrap_or_else(|| { rt.config() - .ok_or_else(|| CE::from("No configuration file".to_owned())) + .ok_or_else(|| Error::from(err_msg("No configuration file"))) .map_err_trace_exit_unwrap(1) .read_string(config_value_path) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) - .ok_or_else(|| CE::from("Configuration 'contact.list_format' does not exist".to_owned())) + .ok_or_else(|| Error::from(err_msg("Configuration 'contact.list_format' does not exist"))) .map_err_trace_exit_unwrap(1) }); let mut hb = Handlebars::new(); let _ = hb .register_template_string("format", fmt) - .err_from_str() - .map_err(CE::from) + .map_err(Error::from) .map_err_trace_exit_unwrap(1); hb.register_escape_fn(::handlebars::no_escape); diff --git a/bin/domain/imag-diary/Cargo.toml b/bin/domain/imag-diary/Cargo.toml index 1e656766..abf7caa0 100644 --- a/bin/domain/imag-diary/Cargo.toml +++ b/bin/domain/imag-diary/Cargo.toml @@ -25,8 +25,9 @@ maintenance = { status = "actively-developed" } chrono = "0.4" log = "0.4.0" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } itertools = "0.7" +failure = "0.1" libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } diff --git a/bin/domain/imag-diary/src/create.rs b/bin/domain/imag-diary/src/create.rs index 4f861cec..6fb730f8 100644 --- a/bin/domain/imag-diary/src/create.rs +++ b/bin/domain/imag-diary/src/create.rs @@ -21,10 +21,11 @@ use clap::ArgMatches; use chrono::NaiveDateTime; use chrono::Local; use chrono::Timelike; +use failure::Error; +use failure::ResultExt; +use failure::err_msg; use libimagdiary::diary::Diary; -use libimagdiary::error::DiaryErrorKind as DEK; -use libimagdiary::error::ResultExt; use libimagentryedit::edit::Edit; use libimagrt::runtime::Runtime; use libimagerror::trace::MapErrTrace; @@ -47,8 +48,7 @@ pub fn create(rt: &Runtime) { Ok(()) } else { debug!("Editing new diary entry"); - entry.edit_content(rt) - .chain_err(|| DEK::DiaryEditError) + entry.edit_content(rt).context(err_msg("Diary edit error")).map_err(Error::from) }; let _ = res.map_err_trace_exit_unwrap(1); @@ -75,7 +75,9 @@ fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLock }) .map(|timed| { let time = create_id_from_clispec(&create, &diaryname, timed); - diary.new_entry_at(&diaryname, &time).chain_err(|| DEK::StoreWriteError) + diary.new_entry_at(&diaryname, &time) + .context(err_msg("Store write error")) + .map_err(Error::from) }) .unwrap_or_else(|| { debug!("Creating non-timed entry"); diff --git a/bin/domain/imag-diary/src/list.rs b/bin/domain/imag-diary/src/list.rs index a40cd0ff..a1f32ff2 100644 --- a/bin/domain/imag-diary/src/list.rs +++ b/bin/domain/imag-diary/src/list.rs @@ -29,9 +29,10 @@ use libimagerror::exit::ExitUnwrap; use libimagutil::debug_result::*; use libimagdiary::diaryid::DiaryId; use libimagdiary::diaryid::FromStoreId; -use libimagdiary::error::Result; use libimagstore::storeid::IntoStoreId; +use failure::Fallible as Result; + use util::get_diary_name; pub fn list(rt: &Runtime) { diff --git a/bin/domain/imag-diary/src/main.rs b/bin/domain/imag-diary/src/main.rs index d48f0288..73a999b5 100644 --- a/bin/domain/imag-diary/src/main.rs +++ b/bin/domain/imag-diary/src/main.rs @@ -33,6 +33,7 @@ )] #[macro_use] extern crate log; +#[macro_use] extern crate failure; extern crate clap; extern crate chrono; extern crate toml; diff --git a/bin/domain/imag-diary/src/util.rs b/bin/domain/imag-diary/src/util.rs index db56b7ca..f5074ff4 100644 --- a/bin/domain/imag-diary/src/util.rs +++ b/bin/domain/imag-diary/src/util.rs @@ -18,10 +18,13 @@ // use libimagrt::runtime::Runtime; -use libimagdiary::error::*; +use libimagerror::errors::ErrorMsg as EM; use toml::Value; use toml_query::read::TomlValueReadExt; +use failure::Error; +use failure::Fallible as Result; +use failure::ResultExt; pub fn get_diary_name(rt: &Runtime) -> Option { use libimagdiary::config::get_default_diary_name; @@ -58,14 +61,15 @@ pub fn get_diary_timed_config(rt: &Runtime, diary_name: &str) -> Result { let v = cfg .read(&format!("diary.diaries.{}.timed", diary_name)) - .chain_err(|| DiaryErrorKind::IOError); + .context(EM::IO) + .map_err(Error::from); match v { Ok(Some(&Value::String(ref s))) => parse_timed_string(s, diary_name).map(Some), Ok(Some(_)) => { let s = format!("Type error at 'diary.diaryies.{}.timed': should be either 'd'/'daily', 'h'/'hourly', 'm'/'minutely' or 's'/'secondly'", diary_name); - Err(s).map_err(From::from) + Err(format_err!("{}", s)) }, Ok(None) => Ok(None), @@ -87,6 +91,6 @@ pub fn parse_timed_string(s: &str, diary_name: &str) -> Result { } else { let s = format!("Cannot parse config: 'diary.diaries.{}.timed = {}'", diary_name, s); - Err(s).map_err(From::from) + Err(format_err!("{}", s)) } } diff --git a/bin/domain/imag-habit/Cargo.toml b/bin/domain/imag-habit/Cargo.toml index 7aee14ae..b7018bfa 100644 --- a/bin/domain/imag-habit/Cargo.toml +++ b/bin/domain/imag-habit/Cargo.toml @@ -25,9 +25,10 @@ maintenance = { status = "actively-developed" } chrono = "0.4" log = "0.4" toml = "0.4" -toml-query = "0.7" -kairos = { git = "https://github.com/matthiasbeyer/kairos", branch = "master" } +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +kairos = { git = "https://github.com/matthiasbeyer/kairos", branch = "failure" } prettytable-rs = "0.8" +failure = "0.1" libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } diff --git a/bin/domain/imag-habit/src/main.rs b/bin/domain/imag-habit/src/main.rs index 63246fd8..6f81e077 100644 --- a/bin/domain/imag-habit/src/main.rs +++ b/bin/domain/imag-habit/src/main.rs @@ -39,6 +39,7 @@ extern crate toml_query; extern crate kairos; extern crate chrono; extern crate prettytable; +#[macro_use] extern crate failure; extern crate libimaghabit; extern crate libimagstore; @@ -53,6 +54,7 @@ use std::process::exit; use prettytable::Table; use prettytable::Cell; use prettytable::Row; +use failure::Error; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; @@ -232,8 +234,7 @@ fn delete(rt: &Runtime) { // future flag. If it is true, the check will not be performed and it is assumed that `--future` // was passed. fn today(rt: &Runtime, future: bool) { - use libimaghabit::error::ResultExt; - use libimaghabit::error::HabitErrorKind as HEK; + use failure::ResultExt; let (future, show_done) = { if !future { @@ -296,7 +297,8 @@ fn today(rt: &Runtime, future: bool) { am.value_of("today-show-next-n") .map(|x| { x.parse::() - .chain_err(|| HEK::from(format!("Cannot parse String '{}' to integer", x))) + .context(format_err!("Cannot parse String '{}' to integer", x)) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) }) }).unwrap_or(5); diff --git a/bin/domain/imag-log/Cargo.toml b/bin/domain/imag-log/Cargo.toml index 98283c17..640f098c 100644 --- a/bin/domain/imag-log/Cargo.toml +++ b/bin/domain/imag-log/Cargo.toml @@ -24,9 +24,10 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } is-match = "0.1" itertools = "0.7" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/domain/imag-log/src/main.rs b/bin/domain/imag-log/src/main.rs index 053f06e5..56d50189 100644 --- a/bin/domain/imag-log/src/main.rs +++ b/bin/domain/imag-log/src/main.rs @@ -38,6 +38,7 @@ extern crate clap; extern crate toml; extern crate toml_query; extern crate itertools; +extern crate failure; extern crate libimaglog; #[macro_use] extern crate libimagrt; @@ -47,6 +48,9 @@ extern crate libimagdiary; use std::io::Write; +use failure::Error; +use failure::err_msg; + use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagerror::trace::MapErrTrace; @@ -55,7 +59,6 @@ use libimagerror::exit::ExitUnwrap; use libimagerror::iter::TraceIterator; use libimagdiary::diary::Diary; use libimaglog::log::Log; -use libimaglog::error::LogError as LE; use libimagstore::iter::get::StoreIdGetIteratorExtension; mod ui; @@ -175,16 +178,17 @@ fn get_diary_name(rt: &Runtime) -> String { let cfg = rt .config() - .ok_or(LE::from("Configuration not present, cannot continue")) + .ok_or_else(|| Error::from(err_msg("Configuration not present, cannot continue"))) .map_err_trace_exit_unwrap(1); let logs = cfg .read("log.logs") + .map_err(Error::from) .map_err_trace_exit_unwrap(1) - .ok_or(LE::from("Configuration missing: 'log.logs'")) + .ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.logs'"))) .map_err_trace_exit_unwrap(1) .as_array() - .ok_or(LE::from("Configuration 'log.logs' is not an Array")) + .ok_or_else(|| Error::from(err_msg("Configuration 'log.logs' is not an Array"))) .map_err_trace_exit_unwrap(1); if !logs.iter().all(|e| is_match!(e, &Value::String(_))) { @@ -201,8 +205,9 @@ fn get_diary_name(rt: &Runtime) -> String { let current_log = cfg .read_string("log.default") + .map_err(Error::from) .map_err_trace_exit_unwrap(1) - .ok_or(LE::from("Configuration missing: 'log.default'")) + .ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.default'"))) .map_err_trace_exit_unwrap(1); if !logs.contains(¤t_log) { diff --git a/bin/domain/imag-mail/Cargo.toml b/bin/domain/imag-mail/Cargo.toml index 08ecff00..5dc1b710 100644 --- a/bin/domain/imag-mail/Cargo.toml +++ b/bin/domain/imag-mail/Cargo.toml @@ -23,6 +23,7 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" +failure = "0.1" libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/bin/domain/imag-mail/src/main.rs b/bin/domain/imag-mail/src/main.rs index f36e01c4..c7975480 100644 --- a/bin/domain/imag-mail/src/main.rs +++ b/bin/domain/imag-mail/src/main.rs @@ -34,6 +34,7 @@ extern crate clap; #[macro_use] extern crate log; +extern crate failure; #[macro_use] extern crate libimagrt; extern crate libimagmail; @@ -42,6 +43,9 @@ extern crate libimagutil; use std::io::Write; +use failure::Error; +use failure::err_msg; + use libimagerror::trace::{MapErrTrace, trace_error}; use libimagerror::iter::TraceIterator; use libimagerror::exit::ExitUnwrap; @@ -91,8 +95,7 @@ fn import_mail(rt: &Runtime) { } fn list(rt: &Runtime) { - use libimagmail::error::MailErrorKind as MEK; - use libimagmail::error::ResultExt; + use failure::ResultExt; // TODO: Implement lister type in libimagmail for this fn list_mail(rt: &Runtime, m: Mail) { @@ -149,7 +152,8 @@ fn list(rt: &Runtime) { .filter_map(|id| { rt.store() .get(id) - .chain_err(|| MEK::RefHandlingError) + .context(err_msg("Ref handling error")) + .map_err(Error::from) .map_err_trace_exit_unwrap(1) .map(|fle| Mail::from_fle(fle).map_err_trace().ok()) }) diff --git a/bin/domain/imag-timetrack/Cargo.toml b/bin/domain/imag-timetrack/Cargo.toml index f19fec86..076f2228 100644 --- a/bin/domain/imag-timetrack/Cargo.toml +++ b/bin/domain/imag-timetrack/Cargo.toml @@ -27,7 +27,8 @@ chrono = "0.4" filters = "0.3" itertools = "0.7" prettytable-rs = "0.8" -kairos = { git = "https://github.com/matthiasbeyer/kairos", branch = "master" } +kairos = { git = "https://github.com/matthiasbeyer/kairos", branch = "failure" } +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/domain/imag-timetrack/src/day.rs b/bin/domain/imag-timetrack/src/day.rs index 1e59a852..378b89dc 100644 --- a/bin/domain/imag-timetrack/src/day.rs +++ b/bin/domain/imag-timetrack/src/day.rs @@ -22,13 +22,13 @@ use std::str::FromStr; use filters::filter::Filter; use chrono::NaiveDateTime; +use failure::Error; use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagerror::io::ToExitCode; use libimagstore::store::FileLockEntry; -use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -44,7 +44,7 @@ pub fn day(rt: &Runtime) -> i32 { let filter = { let start = match cmd.value_of("start").map(NaiveDateTime::from_str) { None => ::chrono::offset::Local::today().and_hms(0, 0, 0).naive_local(), - Some(s) => match s.map_err(TTE::from) { + Some(s) => match s.map_err(Error::from) { Ok(dt) => dt, Err(e) => { trace_error(&e); @@ -55,7 +55,7 @@ pub fn day(rt: &Runtime) -> i32 { let end = match cmd.value_of("end").map(NaiveDateTime::from_str) { None => ::chrono::offset::Local::today().and_hms(23, 59, 59).naive_local(), - Some(s) => match s.map_err(TTE::from) { + Some(s) => match s.map_err(Error::from) { Ok(dt) => dt, Err(e) => { trace_error(&e); @@ -91,7 +91,7 @@ pub fn day(rt: &Runtime) -> i32 { .map_err_trace_exit_unwrap(1) .trace_unwrap() .filter(|e| filter.filter(e)) - .map(|e| -> Result<_, TTE> { + .map(|e| -> Result<_, Error> { debug!("Processing {:?}", e.get_location()); let tag = e.get_timetrack_tag()?; diff --git a/bin/domain/imag-timetrack/src/list.rs b/bin/domain/imag-timetrack/src/list.rs index b6366196..13de6412 100644 --- a/bin/domain/imag-timetrack/src/list.rs +++ b/bin/domain/imag-timetrack/src/list.rs @@ -25,15 +25,17 @@ use prettytable::Cell; use kairos::parser::Parsed; use kairos::parser::parse as kairos_parse; use clap::ArgMatches; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::err_msg; +use failure::Error; use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagstore::store::FileLockEntry; -use libimagtimetrack::error::TimeTrackError; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; -use libimagtimetrack::error::Result; use libimagrt::runtime::Runtime; @@ -63,6 +65,7 @@ pub fn list(rt: &Runtime) -> i32 { ::std::process::exit(1) }, Some(Err(e)) => { + let e = Error::from(e); trace_error(&e); ::std::process::exit(1) } @@ -164,7 +167,8 @@ pub fn list_impl(rt: &Runtime, }) .map_err_trace_exit_unwrap(1) .print(&mut rt.stdout()) - .map_err(|_| TimeTrackError::from(String::from("Failed printing table"))) + .context(err_msg("Failed to print table")) + .map_err(Error::from) .map(|_| 0) .map_err_trace() .unwrap_or(1) diff --git a/bin/domain/imag-timetrack/src/main.rs b/bin/domain/imag-timetrack/src/main.rs index d482d112..a17cd26c 100644 --- a/bin/domain/imag-timetrack/src/main.rs +++ b/bin/domain/imag-timetrack/src/main.rs @@ -41,6 +41,7 @@ extern crate filters; extern crate itertools; extern crate prettytable; extern crate kairos; +extern crate failure; extern crate libimagerror; extern crate libimagstore; diff --git a/bin/domain/imag-timetrack/src/month.rs b/bin/domain/imag-timetrack/src/month.rs index 39ac1735..7a65f64f 100644 --- a/bin/domain/imag-timetrack/src/month.rs +++ b/bin/domain/imag-timetrack/src/month.rs @@ -22,13 +22,13 @@ use std::str::FromStr; use filters::filter::Filter; use chrono::NaiveDateTime; +use failure::Error; use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::io::ToExitCode; use libimagerror::iter::TraceIterator; use libimagstore::store::FileLockEntry; -use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -48,7 +48,7 @@ pub fn month(rt: &Runtime) -> i32 { let start = match cmd.value_of("start").map(::chrono::naive::NaiveDateTime::from_str) { None => NaiveDate::from_ymd(now.year(), now.month(), 1).and_hms(0, 0, 0), - Some(s) => match s.map_err(TTE::from) { + Some(s) => match s.map_err(Error::from) { Ok(dt) => dt, Err(e) => { trace_error(&e); @@ -70,7 +70,7 @@ pub fn month(rt: &Runtime) -> i32 { NaiveDate::from_ymd(year, month, 1).and_hms(0, 0, 0) }, - Some(s) => match s.map_err(TTE::from) { + Some(s) => match s.map_err(Error::from) { Ok(dt) => dt, Err(e) => { trace_error(&e); @@ -106,7 +106,7 @@ pub fn month(rt: &Runtime) -> i32 { .map_err_trace_exit_unwrap(1) .trace_unwrap() .filter(|e| filter.filter(e)) - .map(|e| -> Result<_, TTE> { + .map(|e| -> Result<_, Error> { debug!("Processing {:?}", e.get_location()); let tag = e.get_timetrack_tag()?; diff --git a/bin/domain/imag-timetrack/src/start.rs b/bin/domain/imag-timetrack/src/start.rs index 6827bb30..abf18b93 100644 --- a/bin/domain/imag-timetrack/src/start.rs +++ b/bin/domain/imag-timetrack/src/start.rs @@ -20,10 +20,10 @@ use std::str::FromStr; use chrono::naive::NaiveDateTime; +use failure::Error; use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; -use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagerror::trace::MapErrTrace; @@ -34,7 +34,7 @@ pub fn start(rt: &Runtime) -> i32 { let start = match cmd.value_of("start-time") { None | Some("now") => ::chrono::offset::Local::now().naive_local(), - Some(ndt) => match NaiveDateTime::from_str(ndt).map_err(TTE::from) { + Some(ndt) => match NaiveDateTime::from_str(ndt).map_err(Error::from) { Ok(ndt) => ndt, Err(e) => { trace_error(&e); diff --git a/bin/domain/imag-timetrack/src/stop.rs b/bin/domain/imag-timetrack/src/stop.rs index c4099b52..539c80a4 100644 --- a/bin/domain/imag-timetrack/src/stop.rs +++ b/bin/domain/imag-timetrack/src/stop.rs @@ -21,13 +21,13 @@ use std::str::FromStr; use filters::filter::Filter; use chrono::NaiveDateTime; +use failure::Error; use libimagerror::trace::trace_error; use libimagerror::iter::TraceIterator; use libimagerror::trace::MapErrTrace; use libimagrt::runtime::Runtime; -use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetrackingstore::*; @@ -42,7 +42,7 @@ pub fn stop(rt: &Runtime) -> i32 { let stop_time = match cmd.value_of("stop-time") { None | Some("now") => ::chrono::offset::Local::now().naive_local(), - Some(ndt) => match NaiveDateTime::from_str(ndt).map_err(TTE::from) { + Some(ndt) => match NaiveDateTime::from_str(ndt).map_err(Error::from) { Ok(ndt) => ndt, Err(e) => { trace_error(&e); diff --git a/bin/domain/imag-timetrack/src/track.rs b/bin/domain/imag-timetrack/src/track.rs index ffc9020f..0e709615 100644 --- a/bin/domain/imag-timetrack/src/track.rs +++ b/bin/domain/imag-timetrack/src/track.rs @@ -22,10 +22,10 @@ use std::process::exit; use clap::ArgMatches; use chrono::naive::NaiveDate; use chrono::naive::NaiveDateTime; +use failure::Error; use libimagrt::runtime::Runtime; use libimagerror::trace::trace_error; -use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagerror::trace::MapErrTrace; @@ -43,10 +43,10 @@ pub fn track(rt: &Runtime) -> i32 { match cmd.value_of(clap_name) { Some("now") => Some(::chrono::offset::Local::now().naive_local()), Some(els) => { - match NaiveDateTime::parse_from_str(els, DATE_TIME_PARSE_FMT).map_err(TTE::from) { + match NaiveDateTime::parse_from_str(els, DATE_TIME_PARSE_FMT).map_err(Error::from) { Ok(ndt) => Some(ndt), Err(e_ndt) => { - match NaiveDate::parse_from_str(els, DATE_PARSE_FMT).map_err(TTE::from) { + match NaiveDate::parse_from_str(els, DATE_PARSE_FMT).map_err(Error::from) { Ok(ndt) => Some(ndt.and_hms(0, 0, 0)), Err(e_nd) => { error!("Cannot parse date {}:", errname); diff --git a/bin/domain/imag-timetrack/src/week.rs b/bin/domain/imag-timetrack/src/week.rs index 90da88b6..c8a74520 100644 --- a/bin/domain/imag-timetrack/src/week.rs +++ b/bin/domain/imag-timetrack/src/week.rs @@ -22,13 +22,13 @@ use std::str::FromStr; use filters::filter::Filter; use chrono::NaiveDateTime; +use failure::Error; use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagerror::io::ToExitCode; use libimagstore::store::FileLockEntry; -use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -50,7 +50,7 @@ pub fn week(rt: &Runtime) -> i32 { let start = match cmd .value_of("start") .map(|s| { - ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + ::chrono::naive::NaiveDateTime::from_str(s).map_err(Error::from) }) { None => NaiveDate::from_isoywd(this_week.year(), this_week.week(), Weekday::Mon) @@ -65,7 +65,7 @@ pub fn week(rt: &Runtime) -> i32 { let end = match cmd .value_of("end") .map(|s| { - ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + ::chrono::naive::NaiveDateTime::from_str(s).map_err(Error::from) }) { None => NaiveDate::from_isoywd(this_week.year(), this_week.week(), Weekday::Sun) @@ -104,7 +104,7 @@ pub fn week(rt: &Runtime) -> i32 { .map_err_trace_exit_unwrap(1) .trace_unwrap() .filter(|e| filter.filter(e)) - .map(|e| -> Result<_, TTE> { + .map(|e| -> Result<_, Error> { debug!("Processing {:?}", e.get_location()); let tag = e.get_timetrack_tag()?; diff --git a/bin/domain/imag-timetrack/src/year.rs b/bin/domain/imag-timetrack/src/year.rs index 7904c6d3..2d5c70f1 100644 --- a/bin/domain/imag-timetrack/src/year.rs +++ b/bin/domain/imag-timetrack/src/year.rs @@ -22,13 +22,13 @@ use std::str::FromStr; use filters::filter::Filter; use chrono::NaiveDateTime; +use failure::Error; use libimagerror::trace::trace_error; use libimagerror::trace::MapErrTrace; use libimagerror::iter::TraceIterator; use libimagerror::io::ToExitCode; use libimagstore::store::FileLockEntry; -use libimagtimetrack::error::TimeTrackError as TTE; use libimagtimetrack::timetrackingstore::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; @@ -49,7 +49,7 @@ pub fn year(rt: &Runtime) -> i32 { let start = match cmd .value_of("start") .map(|s| { - ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + ::chrono::naive::NaiveDateTime::from_str(s).map_err(Error::from) }) { None => NaiveDate::from_ymd(now.year(), 1, 1).and_hms(0, 0, 0), @@ -63,7 +63,7 @@ pub fn year(rt: &Runtime) -> i32 { let end = match cmd .value_of("end") .map(|s| { - ::chrono::naive::NaiveDateTime::from_str(s).map_err(TTE::from) + ::chrono::naive::NaiveDateTime::from_str(s).map_err(Error::from) }) { None => { @@ -104,7 +104,7 @@ pub fn year(rt: &Runtime) -> i32 { .map_err_trace_exit_unwrap(1) .trace_unwrap() .filter(|e| filter.filter(e)) - .map(|e| -> Result<_, TTE> { + .map(|e| -> Result<_, Error> { debug!("Processing {:?}", e.get_location()); let tag = e.get_timetrack_tag()?; diff --git a/bin/domain/imag-todo/Cargo.toml b/bin/domain/imag-todo/Cargo.toml index 4d6ca1fb..c6e6b74b 100644 --- a/bin/domain/imag-todo/Cargo.toml +++ b/bin/domain/imag-todo/Cargo.toml @@ -24,8 +24,9 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } is-match = "0.1" +failure = "0.1" libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/bin/domain/imag-todo/src/main.rs b/bin/domain/imag-todo/src/main.rs index 622bcce2..21e477cc 100644 --- a/bin/domain/imag-todo/src/main.rs +++ b/bin/domain/imag-todo/src/main.rs @@ -37,6 +37,7 @@ extern crate clap; extern crate toml; extern crate toml_query; #[macro_use] extern crate is_match; +extern crate failure; #[macro_use] extern crate libimagrt; extern crate libimagerror; @@ -45,6 +46,7 @@ extern crate libimagtodo; use std::process::{Command, Stdio}; use std::io::stdin; use std::io::Write; +use failure::Error; use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; @@ -119,7 +121,7 @@ fn list(rt: &Runtime) { // return Result instead of Result>, which is a real inconvenience. // let no_identifier = |e: &::toml_query::error::Error| -> bool { - is_match!(e.kind(), &::toml_query::error::ErrorKind::IdentifierNotFoundInDocument(_)) + is_match!(e, &::toml_query::error::Error::IdentifierNotFoundInDocument(_)) }; let res = rt.store().all_tasks() // get all tasks @@ -136,7 +138,7 @@ fn list(rt: &Runtime) { }, Err(e) => { if !no_identifier(&e) { - trace_error(&e); + trace_error(&Error::from(e)); } None } diff --git a/bin/domain/imag-wiki/src/main.rs b/bin/domain/imag-wiki/src/main.rs index 5d5969b3..6e586009 100644 --- a/bin/domain/imag-wiki/src/main.rs +++ b/bin/domain/imag-wiki/src/main.rs @@ -48,7 +48,7 @@ fn main() { let version = make_imag_version!(); let rt = generate_runtime_setup("imag-wiki", &version, - "Manage a personal Wiki", + "Personal wiki", build_ui); let wiki_name = rt.cli().value_of("wikiname").unwrap_or("default"); diff --git a/lib/core/libimagerror/Cargo.toml b/lib/core/libimagerror/Cargo.toml index 914bf598..3b2aa969 100644 --- a/lib/core/libimagerror/Cargo.toml +++ b/lib/core/libimagerror/Cargo.toml @@ -20,6 +20,7 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } maintenance = { status = "actively-developed" } [dependencies] -log = "0.4" -ansi_term = "0.11" -error-chain = "0.12" +log = "0.4" +ansi_term = "0.11" +failure = "0.1" +failure_derive = "0.1" diff --git a/lib/core/libimagerror/src/errors.rs b/lib/core/libimagerror/src/errors.rs new file mode 100644 index 00000000..760bdbd1 --- /dev/null +++ b/lib/core/libimagerror/src/errors.rs @@ -0,0 +1,105 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2018 the imag contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +#[derive(Debug, Clone, Eq, PartialEq, Fail)] +pub enum ErrorMsg { + #[fail(display = "IO Error")] + IO, + + #[fail(display = "Locking error")] + LockError, + + #[fail(display = "UTF8 error")] + UTF8Error, + + #[fail(display = "Error in external process")] + ExternalProcessError, + + #[fail(display = "File Error")] + FileError, + + #[fail(display = "File not copied")] + FileNotCopied, + + #[fail(display = "File not created")] + FileNotCreated, + + #[fail(display = "File not found")] + FileNotFound, + + #[fail(display = "Fail not removed")] + FileNotRemoved, + + #[fail(display = "Fail not renamed")] + FileNotRenamed, + + #[fail(display = "File not seeked")] + FileNotSeeked, + + #[fail(display = "File not written")] + FileNotWritten, + + #[fail(display = "Directory not created")] + DirNotCreated, + + + #[fail(display = "Formatting error")] + FormatError, + + + #[fail(display = "ID is locked")] + IdLocked, + + #[fail(display = "Error while converting values")] + ConversionError, + + + #[fail(display = "Entry exists already: {}", _0)] + EntryAlreadyExists(String), + + #[fail(display = "Entry not found: {}", _0)] + EntryNotFound(String), + + #[fail(display = "Entry header error")] + EntryHeaderError, + + #[fail(display = "Entry header type error")] + EntryHeaderTypeError, + + #[fail(display = "Entry header type error at '{}', expected '{}'", _0, _1)] + EntryHeaderTypeError2(&'static str, &'static str), + + #[fail(display = "Entry header read error")] + EntryHeaderReadError, + + #[fail(display = "Entry header write error")] + EntryHeaderWriteError, + + #[fail(display = "Entry header field missing: {}", _0)] + EntryHeaderFieldMissing(&'static str), + + + #[fail(display = "Toml deserialization error")] + TomlDeserError, + + #[fail(display = "Toml querying error")] + TomlQueryError, + +} + diff --git a/lib/core/libimagerror/src/iter.rs b/lib/core/libimagerror/src/iter.rs index 2bca4649..db7de991 100644 --- a/lib/core/libimagerror/src/iter.rs +++ b/lib/core/libimagerror/src/iter.rs @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error_chain::ChainedError; +use failure::Error; /// An iterator that unwraps the `Ok` items of `iter`, while passing the `Err` items to its /// closure `f`. @@ -31,9 +31,10 @@ pub struct UnwrapWith{ f: F } -impl Iterator for UnwrapWith where - I: Iterator>, - F: FnMut(E) +impl Iterator for UnwrapWith + where + I: Iterator>, + F: FnMut(Error) { type Item = T; @@ -41,14 +42,13 @@ impl Iterator for UnwrapWith where fn next(&mut self) -> Option { loop { match self.iter.next() { - Some(Err(e)) => { - (self.f)(e); - }, + Some(Err(e)) => { (self.f)(e); }, Some(Ok(item)) => return Some(item), - None => return None, + None => return None, } } } + #[inline] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); @@ -56,32 +56,14 @@ impl Iterator for UnwrapWith where } } -impl DoubleEndedIterator for UnwrapWith where - I: DoubleEndedIterator>, - F: FnMut(E) -{ - #[inline] - fn next_back(&mut self) -> Option { - loop { - match self.iter.next_back() { - Some(Err(e)) => { - (self.f)(e); - }, - Some(Ok(item)) => return Some(item), - None => return None, - } - } - } -} + /// Iterator helper for Unwrap with exiting on error -pub struct UnwrapExit(I, i32) - where I: Iterator>, - E: ChainedError; +pub struct UnwrapExit(I, i32) + where I: Iterator>; -impl Iterator for UnwrapExit - where I: Iterator>, - E: ChainedError +impl Iterator for UnwrapExit + where I: Iterator>, { type Item = T; @@ -91,9 +73,8 @@ impl Iterator for UnwrapExit } } -impl DoubleEndedIterator for UnwrapExit - where I: DoubleEndedIterator>, - E: ChainedError +impl DoubleEndedIterator for UnwrapExit + where I: DoubleEndedIterator>, { fn next_back(&mut self) -> Option { use trace::MapErrTrace; @@ -102,18 +83,21 @@ impl DoubleEndedIterator for UnwrapExit } /// This trait provides methods that make it easier to work with iterators that yield a `Result`. -pub trait TraceIterator : Iterator> + Sized { - /// Creates an iterator that yields the item in each `Ok` item, while filtering out the `Err` +pub trait TraceIterator : Iterator> + Sized { + /// Creates an iterator that yields the item in each `Ok` item, while filtering out the + /// `Err` /// items. Each filtered `Err` will be trace-logged with [`::trace::trace_error`]. /// /// As with all iterators, the processing is lazy. If you do not use the result of this method, /// nothing will be passed to `::trace::trace_error`, no matter how many `Err` items might /// be present. #[inline] - fn trace_unwrap(self) -> UnwrapWith where E: ChainedError { + fn trace_unwrap(self) -> UnwrapWith { #[inline] - fn trace_error>(err: E) { - eprintln!("{}", err.display_chain()); + fn trace_error(err: Error) { + err.iter_chain().for_each(|cause| { + eprintln!("{}", cause); + }); } self.unwrap_with(trace_error) @@ -127,12 +111,11 @@ pub trait TraceIterator : Iterator> + Sized { /// nothing will be passed to `::trace::trace_error_exit`, no matter how many `Err` items might /// be present. #[inline] - fn trace_unwrap_exit(self, exitcode: i32) -> UnwrapExit - where E: ChainedError - { + fn trace_unwrap_exit(self, exitcode: i32) -> UnwrapExit { UnwrapExit(self, exitcode) } + /// Takes a closure and creates an iterator that will yield the items inside all `Ok` items /// yielded by the original iterator. All `Err` items will be filtered out, and the contents /// of each `Err` will be passed to the closure. @@ -141,50 +124,13 @@ pub trait TraceIterator : Iterator> + Sized { /// for the closure to be called. #[inline] fn unwrap_with(self, f: F) -> UnwrapWith - where F: FnMut(E) + where F: FnMut(Error) { UnwrapWith { iter: self, f } } } -impl TraceIterator for I where - I: Iterator> +impl TraceIterator for I where + I: Iterator> {} -#[cfg(test)] -mod test { - use super::TraceIterator; - - #[derive(Copy, Clone, Eq, PartialEq, Debug)] - struct TestError(i32); - - #[test] - fn test_unwrap_with() { - let original = vec![Ok(1), Err(TestError(2)), Ok(3), Err(TestError(4))]; - let mut errs = vec![]; - - let oks = original - .into_iter() - .unwrap_with(|e|errs.push(e)) - .collect::>(); - - assert_eq!(&oks, &[1, 3]); - assert_eq!(&errs, &[TestError(2), TestError(4)]); - } - - #[test] - fn test_unwrap_with_backward() { - let original = vec![Ok(1), Err(TestError(2)), Ok(3), Err(TestError(4))]; - let mut errs = vec![]; - - let oks = original - .into_iter() - .rev() - .unwrap_with(|e|errs.push(e)) - .collect::>(); - - assert_eq!(&oks, &[3, 1]); - assert_eq!(&errs, &[TestError(4), TestError(2)]); - } - -} diff --git a/lib/core/libimagerror/src/lib.rs b/lib/core/libimagerror/src/lib.rs index a17aa21e..fba36561 100644 --- a/lib/core/libimagerror/src/lib.rs +++ b/lib/core/libimagerror/src/lib.rs @@ -35,11 +35,13 @@ #[macro_use] extern crate log; extern crate ansi_term; -extern crate error_chain; +extern crate failure; +#[macro_use] extern crate failure_derive; -pub mod io; +pub mod errors; pub mod exit; -pub mod trace; +pub mod io; pub mod iter; pub mod str; +pub mod trace; diff --git a/lib/core/libimagerror/src/trace.rs b/lib/core/libimagerror/src/trace.rs index 160fe340..cc184994 100644 --- a/lib/core/libimagerror/src/trace.rs +++ b/lib/core/libimagerror/src/trace.rs @@ -21,7 +21,7 @@ use std::process::exit; use std::fmt::Display; use std::fmt::Formatter; use std::fmt::Result as FmtResult; -use error_chain::ChainedError; +use failure::Error; use ansi_term::Colour::Red; struct ImagTrace<'a, T: 'a + ?Sized>(&'a T); @@ -32,32 +32,34 @@ impl<'a, T: 'a + ?Sized> ImagTrace<'a, T> { } } -impl<'a, T> Display for ImagTrace<'a, T> - where T: ChainedError +impl<'a> Display for ImagTrace<'a, Error> { fn fmt(&self, fmt: &mut Formatter) -> FmtResult { - try!(writeln!(fmt, "{}: {}", Red.blink().paint("ERROR[ 0]"), self.0)); + let _ = writeln!(fmt, "{}: {}", Red.blink().paint("ERROR[ 0]"), self.0)?; - for (i, e) in self.0.iter().enumerate().skip(1) { - try!(writeln!(fmt, "{}: {}", Red.blink().paint(format!("ERROR[{:>4}]", i)), e)); + { + for (i, cause) in self.0.iter_causes().enumerate() { + let _ = writeln!(fmt, + "{prefix}: {error}", + prefix = Red.blink().paint(format!("ERROR[{:>4}]", i)), + error = cause)?; + } } - if let Some(backtrace) = self.0.backtrace() { - try!(writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))); - try!(writeln!(fmt, "{:?}", backtrace)); - } + let _ = writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))?; + let _ = writeln!(fmt, "{:?}", self.0.backtrace())?; Ok(()) } } -pub fn trace_error>(e: &C) { +pub fn trace_error(e: &Error) { eprintln!("{}", ImagTrace::new(e)); } -pub fn trace_error_dbg>(e: &C) { - debug!("{}", e.display_chain()); +pub fn trace_error_dbg(e: &Error) { + debug!("{}", ImagTrace::new(e)); } /// Helper functions for `Result` types to reduce overhead in the following situations: @@ -74,7 +76,7 @@ pub trait MapErrTrace { fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output; } -impl> MapErrTrace for Result { +impl MapErrTrace for Result { type Output = U; /// Simply call `trace_error()` on the Err (if there is one) and return the error. diff --git a/lib/core/libimagrt/Cargo.toml b/lib/core/libimagrt/Cargo.toml index 2ab0b52a..7c31ae64 100644 --- a/lib/core/libimagrt/Cargo.toml +++ b/lib/core/libimagrt/Cargo.toml @@ -25,10 +25,10 @@ toml = "0.4" xdg-basedir = "1.0" itertools = "0.7" ansi_term = "0.11" -is-match = "0.1" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } atty = "0.2" +failure = "0.1" +failure_derive = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/core/libimagrt/src/configuration.rs b/lib/core/libimagrt/src/configuration.rs index 70a13116..a667e446 100644 --- a/lib/core/libimagrt/src/configuration.rs +++ b/lib/core/libimagrt/src/configuration.rs @@ -21,20 +21,19 @@ use std::path::PathBuf; use toml::Value; use clap::App; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; -use error::RuntimeError as RE; -use error::RuntimeErrorKind as REK; -use error::Result; -use error::ResultExt; +use libimagerror::errors::ErrorMsg as EM; /// Get a new configuration object. /// /// The passed runtimepath is used for searching the configuration file, whereas several file /// names are tested. If that does not work, the home directory and the XDG basedir are tested /// with all variants. -/// -/// If that doesn't work either, an error is returned. -pub fn fetch_config(searchpath: &PathBuf) -> Result { +pub fn fetch_config(searchpath: &PathBuf) -> Result> { use std::env; use std::fs::File; use std::io::Read; @@ -65,7 +64,7 @@ pub fn fetch_config(searchpath: &PathBuf) -> Result { .unwrap_or(vec![]), ]; - Itertools::flatten(vals.iter()) + let config = Itertools::flatten(vals.iter()) .filter(|path| path.exists() && path.is_file()) .filter_map(|path| { let content = { @@ -90,13 +89,14 @@ pub fn fetch_config(searchpath: &PathBuf) -> Result { .unwrap_or_else(|| String::from("Line unknown, Column unknown")); let _ = write!(stderr(), "Config file parser error at {}", line_col); - let e : RE = RE::from(e); + let e = Error::from(EM::TomlDeserError); trace_error(&e); None }) }) - .nth(0) - .ok_or(RE::from_kind(REK::ConfigNoConfigFileFound)) + .nth(0); + + Ok(config) } /// Override the configuration. @@ -120,16 +120,16 @@ pub fn override_config(val: &mut Value, v: Vec) -> Result<()> { .map(|(k, v)| { let value = val .read(&k) - .chain_err(|| REK::ConfigTOMLParserError)? - .ok_or(RE::from_kind(REK::ConfigOverrideKeyNotAvailable))?; + .context(EM::TomlQueryError)? + .ok_or_else(|| Error::from(err_msg("Confit parser error")))?; into_value(value, v) .map(|v| info!("Successfully overridden: {} = {}", k, v)) - .ok_or_else(|| RE::from_kind(REK::ConfigOverrideTypeNotMatching)) + .ok_or_else(|| Error::from(err_msg("Config override type not matching"))) }); for elem in iter { - let _ = try!(elem.chain_err(|| REK::ConfigOverrideError)); + let _ = elem.context(err_msg("Config override error"))?; } Ok(()) diff --git a/lib/core/libimagrt/src/error.rs b/lib/core/libimagrt/src/error.rs deleted file mode 100644 index 35331c67..00000000 --- a/lib/core/libimagrt/src/error.rs +++ /dev/null @@ -1,125 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - RuntimeError, RuntimeErrorKind, ResultExt, Result; - } - - foreign_links { - IO(::std::io::Error); - TomlDeError(::toml::de::Error); - TomlQueryError(::toml_query::error::Error); - HandlebarsTemplateError(::handlebars::TemplateError); - } - - errors { - Instantiate { - description("Could not instantiate") - display("Could not instantiate") - } - - IOError { - description("IO Error") - display("IO Error") - } - - ProcessExitFailure { - description("Process exited with failure") - display("Process exited with failure") - } - - IOLogFileOpenError { - description("IO Error: Could not open logfile") - display("IO Error: Could not open logfile") - } - - ConfigTypeError(path: String, should_be_type: &'static str) { - description("Error while reading the configuration: Type Error") - display("Type Error: '{}' should be '{}'", path, should_be_type) - } - - GlobalLogLevelConfigMissing { - description("Global config 'imag.logging.level' missing") - display("Global config 'imag.logging.level' missing") - } - - GlobalDestinationConfigMissing { - description("Global config 'imag.logging.destinations' missing") - display("Global config 'imag.logging.destinations' missing") - } - - InvalidLogLevelSpec { - description("Invalid log level specification: Only 'trace', 'debug', 'info', 'warn', 'error' are allowed") - display("Invalid log level specification: Only 'trace', 'debug', 'info', 'warn', 'error' are allowed") - } - - ConfigMissingLoggingFormatTrace { - description("Missing config for logging format for trace logging") - display("Missing config for logging format for trace logging") - } - - ConfigMissingLoggingFormatDebug { - description("Missing config for logging format for debug logging") - display("Missing config for logging format for debug logging") - } - - ConfigMissingLoggingFormatInfo { - description("Missing config for logging format for info logging") - display("Missing config for logging format for info logging") - } - - ConfigMissingLoggingFormatWarn { - description("Missing config for logging format for warn logging") - display("Missing config for logging format for warn logging") - } - - ConfigMissingLoggingFormatError { - description("Missing config for logging format for error logging") - display("Missing config for logging format for error logging") - } - - ConfigTOMLParserError { - description("Configuration: TOML Parsing error") - display("Configuration: TOML Parsing error") - } - - ConfigNoConfigFileFound { - description("Configuration: No config file found") - display("Configuration: No config file found") - } - - ConfigOverrideError { - description("Configuration: Config override error") - display("Configuration: Config override error") - } - - ConfigOverrideKeyNotAvailable { - description("Configuration: Key not available") - display("Configuration: Key not available") - } - - ConfigOverrideTypeNotMatching { - description("Configuration: Configuration Type not matching") - display("Configuration: Configuration Type not matching") - } - - } -} - diff --git a/lib/core/libimagrt/src/lib.rs b/lib/core/libimagrt/src/lib.rs index d56d638c..aff768d5 100644 --- a/lib/core/libimagrt/src/lib.rs +++ b/lib/core/libimagrt/src/lib.rs @@ -36,17 +36,16 @@ )] #[macro_use] extern crate log; -#[macro_use] extern crate error_chain; extern crate itertools; #[cfg(unix)] extern crate xdg_basedir; extern crate env_logger; extern crate ansi_term; extern crate handlebars; +#[macro_use] extern crate failure; extern crate clap; extern crate toml; extern crate toml_query; -#[macro_use] extern crate is_match; extern crate atty; extern crate libimagstore; @@ -54,7 +53,6 @@ extern crate libimagutil; extern crate libimagerror; extern crate libimaginteraction; -pub mod error; pub mod configuration; pub mod logger; pub mod io; diff --git a/lib/core/libimagrt/src/logger.rs b/lib/core/libimagrt/src/logger.rs index 84b2ecc2..4fd773a6 100644 --- a/lib/core/libimagrt/src/logger.rs +++ b/lib/core/libimagrt/src/logger.rs @@ -24,11 +24,12 @@ use std::sync::Arc; use std::sync::Mutex; use std::ops::Deref; -use error::RuntimeErrorKind as EK; -use error::RuntimeError as RE; -use error::ResultExt; use runtime::Runtime; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; use clap::ArgMatches; use log::{Log, Level, Record, Metadata}; use toml::Value; @@ -36,10 +37,10 @@ use toml_query::read::TomlValueReadExt; use toml_query::read::TomlValueReadTypeExt; use handlebars::Handlebars; -type ModuleName = String; -type Result = ::std::result::Result; +use libimagerror::errors::ErrorMsg as EM; + +type ModuleName = String; -#[derive(Debug)] enum LogDestination { Stderr, File(Arc>), @@ -51,7 +52,6 @@ impl Default for LogDestination { } } -#[derive(Debug)] struct ModuleSettings { enabled: bool, level: Option, @@ -89,32 +89,39 @@ impl ImagLogger { { let fmt = aggregate_global_format_trace(config)?; - handlebars.register_template_string("TRACE", fmt)?; // name must be uppercase + handlebars.register_template_string("TRACE", fmt) + .map_err(Error::from) + .context(err_msg("Handlebars template error"))?; // name must be uppercase } { let fmt = aggregate_global_format_debug(config)?; - handlebars.register_template_string("DEBUG", fmt)?; // name must be uppercase + handlebars.register_template_string("DEBUG", fmt) + .map_err(Error::from) + .context(err_msg("Handlebars template error"))?; // name must be uppercase } { let fmt = aggregate_global_format_info(config)?; - handlebars.register_template_string("INFO", fmt)?; // name must be uppercase + handlebars.register_template_string("INFO", fmt) + .map_err(Error::from) + .context(err_msg("Handlebars template error"))?; // name must be uppercase } { let fmt = aggregate_global_format_warn(config)?; - handlebars.register_template_string("WARN", fmt)?; // name must be uppercase + handlebars.register_template_string("WARN", fmt) + .map_err(Error::from) + .context(err_msg("Handlebars template error"))?; // name must be uppercase } { let fmt = aggregate_global_format_error(config)?; - handlebars.register_template_string("ERROR", fmt)?; // name must be uppercase + handlebars.register_template_string("ERROR", fmt) + .map_err(Error::from) + .context(err_msg("Handlebars template error"))?; // name must be uppercase } - let module_settings = aggregate_module_settings(matches, config)?; - eprintln!("Logging: {:?}", module_settings); - Ok(ImagLogger { global_loglevel : aggregate_global_loglevel(matches, config)?, global_destinations : aggregate_global_destinations(matches, config)?, - module_settings : module_settings, + module_settings : aggregate_module_settings(matches, config)?, handlebars : handlebars, }) } @@ -179,35 +186,28 @@ impl Log for ImagLogger { self.module_settings .get(record_target) .map(|module_setting| { - // We have a module setting some - // * Check whether logging is enabled for this module and - // * check whether the module logging level is >= or, if there is no module logging - // level, - // * check whether the global logging level is >= the record level. let set = module_setting.enabled && module_setting.level.unwrap_or(self.global_loglevel) >= record.level(); - if set { // if we want to log from a setting standpoint - // get the destinations for the module and log to all of them + if set { module_setting.destinations.as_ref().map(|destinations| for d in destinations { - let _ = log_to_destination(&d); // ignore errors, because what else? + // If there's an error, we cannot do anything, can we? + let _ = log_to_destination(&d); }); - // after that, log to the global destinations as well for d in self.global_destinations.iter() { - let _ = log_to_destination(&d); // ignore errors, because what else? + // If there's an error, we cannot do anything, can we? + let _ = log_to_destination(&d); } } }) - - // if we do not have a setting for the record target .unwrap_or_else(|| { - if self.global_loglevel >= record.level() { // if logging is enabled for that level - self.global_destinations - .iter() - .for_each(|d| { // log to all global destinations - let _ = log_to_destination(&d); // ignore errors, because what else? - }); + if self.global_loglevel >= record.level() { + // Yes, we log + for d in self.global_destinations.iter() { + // If there's an error, we cannot do anything, can we? + let _ = log_to_destination(&d); + } } }); } @@ -220,7 +220,7 @@ fn match_log_level_str(s: &str) -> Result { "info" => Ok(Level::Info), "warn" => Ok(Level::Warn), "error" => Ok(Level::Error), - _ => return Err(RE::from_kind(EK::InvalidLogLevelSpec)), + lvl => return Err(format_err!("Invalid logging level: {}", lvl)), } } @@ -243,8 +243,10 @@ fn aggregate_global_loglevel(matches: &ArgMatches, config: Option<&Value>) -> Re if let Some(cfg) = config { let cfg_loglevel = cfg - .read_string("imag.logging.level")? - .ok_or(RE::from_kind(EK::GlobalLogLevelConfigMissing)) + .read_string("imag.logging.level") + .map_err(Error::from) + .context(EM::TomlQueryError)? + .ok_or(err_msg("Global log level config missing")) .and_then(|s| match_log_level_str(&s))?; if let Some(cli_loglevel) = get_arg_loglevel(matches)? { @@ -273,7 +275,9 @@ fn translate_destination(raw: &str) -> Result { .map(Mutex::new) .map(Arc::new) .map(LogDestination::File) - .chain_err(|| EK::IOLogFileOpenError) + .map_err(Error::from) + .context(EM::IO) + .map_err(Error::from) } } } @@ -285,9 +289,9 @@ fn translate_destinations(raw: &Vec) -> Result> { acc.and_then(|mut v| { let dest = val.as_str() .ok_or_else(|| { - let path = "imag.logging.modules..destinations".to_owned(); + let path = "imag.logging.modules..destinations"; let ty = "Array"; - RE::from_kind(EK::ConfigTypeError(path, ty)) + Error::from(format_err!("Type error at {}, expected {}", path, ty)) }) .and_then(translate_destination)?; v.push(dest); @@ -299,16 +303,18 @@ fn translate_destinations(raw: &Vec) -> Result> { fn aggregate_global_destinations(matches: &ArgMatches, config: Option<&Value>) -> Result> { - let config_log_dest_path = "imag.logging.destinations"; + match config { Some(cfg) => cfg - .read(&config_log_dest_path)? - .ok_or_else(|| RE::from_kind(EK::GlobalDestinationConfigMissing))? + .read("imag.logging.destinations") + .map_err(Error::from) + .context(EM::TomlQueryError)? + .ok_or_else(|| err_msg("Global log destination config missing"))? .as_array() .ok_or_else(|| { - let path = config_log_dest_path.to_owned(); + let path = "imag.logging.destinations"; let ty = "Array"; - RE::from_kind(EK::ConfigTypeError(path, ty)) + Error::from(format_err!("Type error at {}, expected {}", path, ty)) }) .and_then(translate_destinations), None => { @@ -330,10 +336,12 @@ fn aggregate_global_destinations(matches: &ArgMatches, config: Option<&Value>) } macro_rules! aggregate_global_format { - ($read_str:expr, $error_kind_if_missing:expr, $config:expr) => { - try!($config.ok_or(RE::from_kind($error_kind_if_missing))) - .read_string($read_str)? - .ok_or_else(|| RE::from_kind($error_kind_if_missing)) + ($read_str:expr, $error_msg_if_missing:expr, $config:expr) => { + try!($config.ok_or_else(|| Error::from(err_msg($error_msg_if_missing)))) + .read_string($read_str) + .map_err(Error::from) + .context(EM::TomlQueryError)? + .ok_or_else(|| Error::from(err_msg($error_msg_if_missing))) }; } @@ -341,43 +349,43 @@ fn aggregate_global_format_trace(config: Option<&Value>) -> Result { aggregate_global_format!("imag.logging.format.trace", - EK::ConfigMissingLoggingFormatTrace, - config) + "Config missing: Logging format: Trace", + config) } fn aggregate_global_format_debug(config: Option<&Value>) -> Result { aggregate_global_format!("imag.logging.format.debug", - EK::ConfigMissingLoggingFormatDebug, - config) + "Config missing: Logging format: Debug", + config) } fn aggregate_global_format_info(config: Option<&Value>) -> Result { aggregate_global_format!("imag.logging.format.info", - EK::ConfigMissingLoggingFormatInfo, - config) + "Config missing: Logging format: Info", + config) } fn aggregate_global_format_warn(config: Option<&Value>) -> Result { aggregate_global_format!("imag.logging.format.warn", - EK::ConfigMissingLoggingFormatWarn, - config) + "Config missing: Logging format: Warn", + config) } fn aggregate_global_format_error(config: Option<&Value>) -> Result { aggregate_global_format!("imag.logging.format.error", - EK::ConfigMissingLoggingFormatError, - config) + "Config missing: Logging format: Error", + config) } -fn aggregate_module_settings(matches: &ArgMatches, config: Option<&Value>) +fn aggregate_module_settings(_matches: &ArgMatches, config: Option<&Value>) -> Result> { // Helper macro to return the error from Some(Err(_)) and map everything else to an @@ -393,44 +401,43 @@ fn aggregate_module_settings(matches: &ArgMatches, config: Option<&Value>) }; match config { - Some(cfg) => match cfg.read("imag.logging.modules") { + Some(cfg) => match cfg.read("imag.logging.modules").map_err(Error::from) { Ok(Some(&Value::Table(ref t))) => { // translate the module settings from the table `t` let mut settings = BTreeMap::new(); for (module_name, v) in t { let destinations = inner_try! { - v.read("destinations")? + v.read("destinations") + .map_err(Error::from) + .context(EM::TomlQueryError)? .map(|val| { val.as_array() .ok_or_else(|| { - let path = "imag.logging.modules..destinations".to_owned(); + let path = "imag.logging.modules..destinations"; let ty = "Array"; - RE::from_kind(EK::ConfigTypeError(path, ty)) + Error::from(format_err!("Type error at {}, expected {}", path, ty)) }) .and_then(translate_destinations) }) }; - - let (pre_enabled, level) = if matches.is_present(Runtime::arg_debugging_name()) { - (true, Some(Level::Debug)) - } else { - let level = inner_try! { - v.read_string("level")?.map(|s| match_log_level_str(&s)) - }; - - (false, level) + let level = inner_try! { + v.read_string("level") + .map_err(Error::from) + .context(EM::TomlQueryError)? + .map(|s| match_log_level_str(&s)) }; - let enabled = pre_enabled || - v.read("enabled")? - .map(|v| v.as_bool().unwrap_or(false)) - .ok_or_else(|| { - let path = "imag.logging.modules..enabled".to_owned(); - let ty = "Boolean"; - RE::from_kind(EK::ConfigTypeError(path, ty)) - })?; + let enabled = v.read("enabled") + .map_err(Error::from) + .context(EM::TomlQueryError)? + .map(|v| v.as_bool().unwrap_or(false)) + .ok_or_else(|| { + let path = "imag.logging.modules..enabled"; + let ty = "Boolean"; + Error::from(format_err!("Type error at {}, expected {}", path, ty)) + })?; let module_settings = ModuleSettings { enabled: enabled, @@ -445,15 +452,15 @@ fn aggregate_module_settings(matches: &ArgMatches, config: Option<&Value>) Ok(settings) }, Ok(Some(_)) => { - let path = "imag.logging.modules".to_owned(); + let path = "imag.logging.modules"; let ty = "Table"; - Err(RE::from_kind(EK::ConfigTypeError(path, ty))) + Err(Error::from(format_err!("Type error at {}, expected {}", path, ty))) }, Ok(None) => { // No modules configured. This is okay! Ok(BTreeMap::new()) }, - Err(e) => Err(e).map_err(From::from), + Err(e) => Err(e).context(EM::TomlQueryError).map_err(Error::from), }, None => { write!(stderr(), "No Configuration.").ok(); diff --git a/lib/core/libimagrt/src/runtime.rs b/lib/core/libimagrt/src/runtime.rs index 4e72404d..4dfe3b5f 100644 --- a/lib/core/libimagrt/src/runtime.rs +++ b/lib/core/libimagrt/src/runtime.rs @@ -30,14 +30,16 @@ use toml::Value; use toml_query::read::TomlValueReadExt; use clap::{Arg, ArgMatches}; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; use configuration::{fetch_config, override_config, InternalConfiguration}; -use error::RuntimeError; -use error::RuntimeErrorKind; -use error::ResultExt; use logger::ImagLogger; use io::OutputProxy; +use libimagerror::errors::ErrorMsg as EM; use libimagerror::trace::*; use libimagstore::store::Store; use libimagstore::file_abstraction::InMemoryFileAbstraction; @@ -62,7 +64,7 @@ impl<'a> Runtime<'a> { /// and builds the Runtime object with it. /// /// The cli_app object should be initially build with the ::get_default_cli_builder() function. - pub fn new(cli_app: C) -> Result, RuntimeError> + pub fn new(cli_app: C) -> Result> where C: Clone + CliSpec<'a> + InternalConfiguration { use libimagerror::trace::trace_error; @@ -76,17 +78,15 @@ impl<'a> Runtime<'a> { debug!("Config path = {:?}", configpath); - let config = match fetch_config(&configpath) { - Err(e) => if !is_match!(e.kind(), &RuntimeErrorKind::ConfigNoConfigFileFound) { - return Err(e).chain_err(|| RuntimeErrorKind::Instantiate); - } else { - eprintln!("No config file found."); - eprintln!("Maybe try to use 'imag-init' to initialize imag?"); - eprintln!("Continuing without configuration file"); - None + let config = match fetch_config(&configpath)? { + None => { + return Err(err_msg("No configuration file found")) + .context(err_msg("Maybe try to use 'imag-init' to initialize imag?")) + .context(err_msg("Continuing without configuration file")) + .context(err_msg("Cannot instantiate runtime")) + .map_err(Error::from); }, - - Ok(mut config) => { + Some(mut config) => { if let Err(e) = override_config(&mut config, get_override_specs(&matches)) { error!("Could not apply config overrides"); trace_error(&e); @@ -102,16 +102,14 @@ impl<'a> Runtime<'a> { } /// Builds the Runtime object using the given `config`. - pub fn with_configuration(cli_app: C, config: Option) - -> Result, RuntimeError> + pub fn with_configuration(cli_app: C, config: Option) -> Result> where C: Clone + CliSpec<'a> + InternalConfiguration { let matches = cli_app.clone().matches(); Runtime::_new(cli_app, matches, config) } - fn _new(cli_app: C, matches: ArgMatches<'a>, config: Option) - -> Result, RuntimeError> + fn _new(cli_app: C, matches: ArgMatches<'a>, config: Option) -> Result> where C: Clone + CliSpec<'a> + InternalConfiguration { if cli_app.enable_logging() { @@ -146,7 +144,8 @@ impl<'a> Runtime<'a> { store: store, } }) - .chain_err(|| RuntimeErrorKind::Instantiate) + .context(err_msg("Cannot instantiate runtime")) + .map_err(Error::from) } /// @@ -379,7 +378,7 @@ impl<'a> Runtime<'a> { } /// Get a editor command object which can be called to open the $EDITOR - pub fn editor(&self) -> Result, RuntimeError> { + pub fn editor(&self) -> Result> { self.cli() .value_of("editor") .map(String::from) @@ -391,7 +390,7 @@ impl<'a> Runtime<'a> { }) }) .or(env::var("EDITOR").ok()) - .ok_or_else(|| RuntimeErrorKind::IOError.into()) + .ok_or_else(|| Error::from(EM::IO)) .map_dbg(|s| format!("Editing with '{}'", s)) .and_then(|s| { let mut split = s.split_whitespace(); @@ -401,7 +400,7 @@ impl<'a> Runtime<'a> { } let mut c = Command::new(command.unwrap()); // secured above c.args(split); - c.stdin(::std::fs::File::open("/dev/tty")?); + c.stdin(::std::fs::File::open("/dev/tty").context(EM::IO)?); c.stderr(::std::process::Stdio::inherit()); Ok(Some(c)) }) @@ -442,8 +441,6 @@ impl<'a> Runtime<'a> { /// # Return value /// /// On success, the exit status object of the `Command` invocation is returned. - /// On Error, a RuntimeError object is returned. This is also the case if writing the error - /// message does not work. /// /// # Details /// @@ -457,7 +454,7 @@ impl<'a> Runtime<'a> { command: S, subcommand: S, args: &ArgMatches) - -> Result<::std::process::ExitStatus, RuntimeError> + -> Result<::std::process::ExitStatus> { use std::io::Write; use std::io::ErrorKind; @@ -465,8 +462,7 @@ impl<'a> Runtime<'a> { let rtp_str = self.rtp() .to_str() .map(String::from) - .ok_or(RuntimeErrorKind::IOError) - .map_err(RuntimeError::from_kind)?; + .ok_or_else(|| Error::from(EM::IO))?; let command = format!("{}-{}", command.as_ref(), subcommand.as_ref()); @@ -497,7 +493,8 @@ impl<'a> Runtime<'a> { }, _ => e, }) - .map_err(RuntimeError::from) + .context(EM::IO) + .map_err(Error::from) } } diff --git a/lib/core/libimagstore/Cargo.toml b/lib/core/libimagstore/Cargo.toml index a4da0a4b..1c8878ba 100644 --- a/lib/core/libimagstore/Cargo.toml +++ b/lib/core/libimagstore/Cargo.toml @@ -29,8 +29,8 @@ walkdir = "2" is-match = "0.1" serde = "1" serde_json = "1" -error-chain = "0.12" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagutil = { version = "0.9.0", path = "../../../lib/etc/libimagutil" } diff --git a/lib/core/libimagstore/src/configuration.rs b/lib/core/libimagstore/src/configuration.rs index d09ef41a..17038c16 100644 --- a/lib/core/libimagstore/src/configuration.rs +++ b/lib/core/libimagstore/src/configuration.rs @@ -19,9 +19,11 @@ use toml::Value; -use store::Result; -use error::StoreError as SE; -use error::StoreErrorKind as SEK; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; + +use libimagerror::errors::ErrorMsg as EM; /// Checks whether the store configuration has a key "implicit-create" which maps to a boolean /// value. If that key is present, the boolean is returned, otherwise false is returned. @@ -31,7 +33,10 @@ pub fn config_implicit_store_create_allowed(config: &Option) -> Result and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -use std::path::PathBuf; - -use storeid::StoreId; - -error_chain! { - types { - StoreError, StoreErrorKind, ResultExt, Result; - } - - foreign_links { - Io(::std::io::Error); - Fmt(::std::fmt::Error); - TomlDeserError(::toml::de::Error); - TomlSerError(::toml::ser::Error); - GlobPatternError(::glob::PatternError); - TomlQueryError(::toml_query::error::Error); - } - - errors { - - ConfigurationError { - description("Store Configuration Error") - display("Store Configuration Error") - } - - ConfigTypeError(key: &'static str, expected: &'static str) { - description("Store configuration type error") - display("Store configuration type error at '{}', expected {}", key, expected) - } - - ConfigKeyMissingError(key: &'static str) { - description("Configuration Key missing") - display("Configuration Key missing: '{}'", key) - } - - VersionError { - description("Incompatible store versions detected") - display("Incompatible store versions detected") - } - - CreateStoreDirDenied { - description("Creating store directory implicitely denied") - display("Creating store directory implicitely denied") - } - - FileError { - description("File Error") - display("File Error") - } - - IoError { - description("IO Error") - display("IO Error") - } - - IdLocked { - description("ID locked") - display("ID locked") - } - - IdNotFound(sid: StoreId) { - description("ID not found") - display("ID not found: {}", sid) - } - - FileNotFound { - description("File corresponding to ID not found") - display("File corresponding to ID not found") - } - - FileNotCreated { - description("File corresponding to ID could not be created") - display("File corresponding to ID could not be created") - } - - FileNotWritten { - description("File corresponding to ID could not be written to") - display("File corresponding to ID could not be written to") - } - - FileNotSeeked { - description("File corresponding to ID could not be seeked") - display("File corresponding to ID could not be seeked") - } - - FileNotRemoved { - description("File corresponding to ID could not be removed") - display("File corresponding to ID could not be removed") - } - - FileNotRenamed { - description("File corresponding to ID could not be renamed") - display("File corresponding to ID could not be renamed") - } - - FileNotCopied { - description("File could not be copied") - display("File could not be copied") - } - - DirNotCreated { - description("Directory/Directories could not be created") - display("Directory/Directories could not be created") - } - - StorePathExists(pb: PathBuf) { - description("Store path exists") - display("Store path exists: {:?}", pb) - } - - StorePathCreate(pb: PathBuf) { - description("Store path create") - display("Store path create: {:?}", pb) - } - - LockError { - description("Error locking datastructure") - display("Error locking datastructure") - } - - LockPoisoned { - description("The internal Store Lock has been poisoned") - display("The internal Store Lock has been poisoned") - } - - EntryAlreadyBorrowed(id: StoreId) { - description("Entry is already borrowed") - display("Entry is already borrowed: {:?}", id) - } - - EntryAlreadyExists(id: StoreId) { - description("Entry already exists") - display("Entry already exists: {:?}", id) - } - - MalformedEntry { - description("Entry has invalid formatting, missing header") - display("Entry has invalid formatting, missing header") - } - - HeaderTypeFailure { - description("Header type is wrong") - display("Header type is wrong") - } - - EncodingError { - description("Encoding error") - display("Encoding error") - } - - EntryRenameError(old: PathBuf, new: PathBuf) { - description("Entry rename error") - display("Entry rename error: {:?} -> {:?}", old, new) - } - - StoreIdHandlingError { - description("StoreId handling error") - display("StoreId handling error") - } - - StoreIdLocalPartAbsoluteError(pb: PathBuf) { - description("StoreId 'id' part is absolute (starts with '/') which is not allowed") - display("StoreId 'id' part is absolute (starts with '/') which is not allowed: {:?}", pb) - } - - StoreIdBuildFromFullPathError { - description("Building StoreId from full file path failed") - display("Building StoreId from full file path failed") - } - - StoreIdHasNoBaseError(pb: PathBuf) { - description("StoreId has no 'base' part") - display("StoreId has no 'base' part: {:?}", pb) - } - - CreateCallError(sid: StoreId) { - description("Error when calling create()") - display("Error when calling create({:?})", sid) - } - - RetrieveCallError(sid: StoreId) { - description("Error when calling retrieve()") - display("Error when calling retrieve({:?})", sid) - } - - GetCallError(sid: StoreId) { - description("Error when calling get()") - display("Error when calling get({:?})", sid) - } - - UpdateCallError(sid: StoreId) { - description("Error when calling update()") - display("Error when calling update({:?})", sid) - } - - RetrieveCopyCallError(sid: StoreId) { - description("Error when calling retrieve_copy()") - display("Error when calling retrieve_copy({:?})", sid) - } - - DeleteCallError(sid: StoreId) { - description("Error when calling delete()") - display("Error when calling delete({:?})", sid) - } - - MoveCallError(old: StoreId, new: StoreId) { - description("Error when calling move()") - display("Error when calling move({:?} -> {:?})", old, new) - } - - // Parser-related errors - - MissingMainSection { - description("Missing main section") - display("Missing main section") - } - - MissingVersionInfo { - description("Missing version information in main section") - display("Missing version information in main section") - } - - NonTableInBaseTable { - description("A non-table was found in the base table") - display("A non-table was found in the base table") - } - - HeaderInconsistency { - description("The header is inconsistent") - display("The header is inconsistent") - } - } -} - diff --git a/lib/core/libimagstore/src/file_abstraction/fs.rs b/lib/core/libimagstore/src/file_abstraction/fs.rs index 1e47e0e7..131edcba 100644 --- a/lib/core/libimagstore/src/file_abstraction/fs.rs +++ b/lib/core/libimagstore/src/file_abstraction/fs.rs @@ -22,8 +22,7 @@ use std::io::{Seek, SeekFrom, Read}; use std::path::{Path, PathBuf}; use std::sync::Arc; -use error::{StoreError as SE, StoreErrorKind as SEK}; -use error::ResultExt; +use libimagerror::errors::ErrorMsg as EM; use super::FileAbstraction; use super::FileAbstractionInstance; @@ -34,6 +33,9 @@ use file_abstraction::iter::PathIterator; use file_abstraction::iter::PathIterBuilder; use walkdir::WalkDir; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::Error; #[derive(Debug)] pub struct FSFileAbstractionInstance(PathBuf); @@ -43,34 +45,41 @@ impl FileAbstractionInstance for FSFileAbstractionInstance { /** * Get the content behind this file */ - fn get_file_content(&mut self, id: StoreId) -> Result { + fn get_file_content(&mut self, id: StoreId) -> Result> { debug!("Getting lazy file: {:?}", self); - let mut file = open_file(&self.0) - .chain_err(|| SEK::FileNotFound)?; + let mut file = match open_file(&self.0) { + Err(err) => return Err(Error::from(err)), + Ok(None) => return Ok(None), + Ok(Some(file)) => file, + }; - file.seek(SeekFrom::Start(0)).chain_err(|| SEK::FileNotSeeked)?; + file.seek(SeekFrom::Start(0)).context(EM::FileNotSeeked)?; let mut s = String::new(); file.read_to_string(&mut s) - .chain_err(|| SEK::IoError) + .context(EM::IO) + .map_err(Error::from) .map(|_| s) - .and_then(|s| Entry::from_str(id, &s)) + .and_then(|s: String| Entry::from_str(id, &s)) + .map(Some) } /** * Write the content of this file */ - fn write_file_content(&mut self, buf: &Entry) -> Result<(), SE> { + fn write_file_content(&mut self, buf: &Entry) -> Result<()> { use std::io::Write; let buf = buf.to_str()?.into_bytes(); - let mut file = create_file(&self.0).chain_err(|| SEK::FileNotCreated)?; + let mut file = create_file(&self.0).context(EM::FileNotCreated)?; - file.seek(SeekFrom::Start(0)).chain_err(|| SEK::FileNotCreated)?; - file.set_len(buf.len() as u64).chain_err(|| SEK::FileNotWritten)?; - file.write_all(&buf).chain_err(|| SEK::FileNotWritten) + file.seek(SeekFrom::Start(0)).context(EM::FileNotCreated)?; + file.set_len(buf.len() as u64).context(EM::FileNotWritten)?; + file.write_all(&buf) + .context(EM::FileNotWritten) + .map_err(Error::from) } } @@ -82,19 +91,24 @@ pub struct FSFileAbstraction {} impl FileAbstraction for FSFileAbstraction { - fn remove_file(&self, path: &PathBuf) -> Result<(), SE> { - remove_file(path).chain_err(|| SEK::FileNotRemoved) + fn remove_file(&self, path: &PathBuf) -> Result<()> { + remove_file(path) + .context(EM::FileNotRemoved) + .map_err(Error::from) } - fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> { - copy(from, to).chain_err(|| SEK::FileNotCopied).map(|_| ()) + fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<()> { + copy(from, to) + .map(|_| ()) + .context(EM::FileNotCopied) + .map_err(Error::from) } - fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> { + fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<()> { match to.parent() { Some(p) => if !p.exists() { debug!("Creating: {:?}", p); - let _ = create_dir_all(&PathBuf::from(p))?; + let _ = create_dir_all(&PathBuf::from(p)).context(EM::DirNotCreated)?; }, None => { debug!("Failed to find parent. This looks like it will fail now"); @@ -103,19 +117,23 @@ impl FileAbstraction for FSFileAbstraction { } debug!("Renaming {:?} to {:?}", from, to); - rename(from, to).chain_err(|| SEK::FileNotRenamed) + rename(from, to) + .context(EM::FileNotRenamed) + .map_err(Error::from) } - fn create_dir_all(&self, path: &PathBuf) -> Result<(), SE> { + fn create_dir_all(&self, path: &PathBuf) -> Result<()> { debug!("Creating: {:?}", path); - create_dir_all(path).chain_err(|| SEK::DirNotCreated) + create_dir_all(path) + .context(EM::DirNotCreated) + .map_err(Error::from) } - fn exists(&self, path: &PathBuf) -> Result { + fn exists(&self, path: &PathBuf) -> Result { Ok(path.exists()) } - fn is_file(&self, path: &PathBuf) -> Result { + fn is_file(&self, path: &PathBuf) -> Result { Ok(path.is_file()) } @@ -124,13 +142,13 @@ impl FileAbstraction for FSFileAbstraction { } /// We return nothing from the FS here. - fn drain(&self) -> Result { + fn drain(&self) -> Result { Ok(Drain::empty()) } /// FileAbstraction::fill implementation that consumes the Drain and writes everything to the /// filesystem - fn fill(&mut self, mut d: Drain) -> Result<(), SE> { + fn fill(&mut self, mut d: Drain) -> Result<()> { d.iter() .fold(Ok(()), |acc, (path, element)| { acc.and_then(|_| self.new_instance(path).write_file_content(&element)) @@ -141,7 +159,7 @@ impl FileAbstraction for FSFileAbstraction { basepath: PathBuf, storepath: PathBuf, backend: Arc) - -> Result + -> Result { trace!("Building PathIterator object"); Ok(PathIterator::new(Box::new(WalkDirPathIterBuilder { basepath }), storepath, backend)) @@ -153,13 +171,15 @@ pub(crate) struct WalkDirPathIterBuilder { } impl PathIterBuilder for WalkDirPathIterBuilder { - fn build_iter(&self) -> Box>> { + fn build_iter(&self) -> Box>> { Box::new(WalkDir::new(self.basepath.clone()) .min_depth(1) .max_open(100) .into_iter() .map(|r| { - r.map(|e| PathBuf::from(e.path())).chain_err(|| SE::from_kind(SEK::FileError)) + r.map(|e| PathBuf::from(e.path())) + .context(format_err!("Error in Walkdir")) + .map_err(Error::from) })) } @@ -168,8 +188,16 @@ impl PathIterBuilder for WalkDirPathIterBuilder { } } -fn open_file>(p: A) -> ::std::io::Result { - OpenOptions::new().write(true).read(true).open(p) +fn open_file>(p: A) -> ::std::io::Result> { + match OpenOptions::new().write(true).read(true).open(p) { + Err(e) => { + match e.kind() { + ::std::io::ErrorKind::NotFound => return Ok(None), + _ => return Err(e), + } + }, + Ok(file) => Ok(Some(file)) + } } fn create_file>(p: A) -> ::std::io::Result { diff --git a/lib/core/libimagstore/src/file_abstraction/inmemory.rs b/lib/core/libimagstore/src/file_abstraction/inmemory.rs index 03b5cb86..a499b697 100644 --- a/lib/core/libimagstore/src/file_abstraction/inmemory.rs +++ b/lib/core/libimagstore/src/file_abstraction/inmemory.rs @@ -18,15 +18,17 @@ // use std::path::PathBuf; - -use error::StoreError as SE; -use error::StoreErrorKind as SEK; use std::collections::HashMap; use std::sync::Mutex; use std::cell::RefCell; use std::sync::Arc; use std::ops::Deref; +use libimagerror::errors::ErrorMsg as EM; + +use failure::Fallible as Result; +use failure::Error; + use super::FileAbstraction; use super::FileAbstractionInstance; use super::Drain; @@ -62,21 +64,21 @@ impl FileAbstractionInstance for InMemoryFileAbstractionInstance { /** * Get the mutable file behind a InMemoryFileAbstraction object */ - fn get_file_content(&mut self, _: StoreId) -> Result { + fn get_file_content(&mut self, _: StoreId) -> Result> { debug!("Getting lazy file: {:?}", self); self.fs_abstraction .lock() - .map_err(|_| SE::from_kind(SEK::LockError)) - .and_then(|mut mtx| { + .map_err(|_| Error::from(EM::LockError)) + .map(|mut mtx| { mtx.get_mut() .get(&self.absent_path) .cloned() - .ok_or_else(|| SE::from_kind(SEK::FileNotFound)) }) + .map_err(Error::from) } - fn write_file_content(&mut self, buf: &Entry) -> Result<(), SE> { + fn write_file_content(&mut self, buf: &Entry) -> Result<()> { match *self { InMemoryFileAbstractionInstance { ref absent_path, .. } => { let mut mtx = self.fs_abstraction.lock().expect("Locking Mutex failed"); @@ -99,18 +101,19 @@ impl InMemoryFileAbstraction { &self.virtual_filesystem } - fn backend_cloned<'a>(&'a self) -> Result, SE> { + fn backend_cloned<'a>(&'a self) -> Result> { self.virtual_filesystem .lock() - .map_err(|_| SE::from_kind(SEK::LockError)) + .map_err(|_| Error::from(EM::LockError)) .map(|mtx| mtx.deref().borrow().clone()) + .into() } } impl FileAbstraction for InMemoryFileAbstraction { - fn remove_file(&self, path: &PathBuf) -> Result<(), SE> { + fn remove_file(&self, path: &PathBuf) -> Result<()> { debug!("Removing: {:?}", path); self.backend() .lock() @@ -118,43 +121,43 @@ impl FileAbstraction for InMemoryFileAbstraction { .get_mut() .remove(path) .map(|_| ()) - .ok_or_else(|| SE::from_kind(SEK::FileNotFound)) + .ok_or_else(|| EM::FileNotFound.into()) } - fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> { + fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<()> { debug!("Copying : {:?} -> {:?}", from, to); let mut mtx = self.backend().lock().expect("Locking Mutex failed"); let backend = mtx.get_mut(); - let a = backend.get(from).cloned().ok_or_else(|| SE::from_kind(SEK::FileNotFound))?; + let a = backend.get(from).cloned().ok_or_else(|| EM::FileNotFound)?; backend.insert(to.clone(), a); debug!("Copying: {:?} -> {:?} worked", from, to); Ok(()) } - fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE> { + fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<()> { debug!("Renaming: {:?} -> {:?}", from, to); let mut mtx = self.backend().lock().expect("Locking Mutex failed"); let backend = mtx.get_mut(); - let a = backend.remove(from).ok_or_else(|| SE::from_kind(SEK::FileNotFound))?; + let a = backend.get(from).cloned().ok_or_else(|| EM::FileNotFound)?; backend.insert(to.clone(), a); debug!("Renaming: {:?} -> {:?} worked", from, to); Ok(()) } - fn create_dir_all(&self, _: &PathBuf) -> Result<(), SE> { + fn create_dir_all(&self, _: &PathBuf) -> Result<()> { Ok(()) } - fn exists(&self, pb: &PathBuf) -> Result { + fn exists(&self, pb: &PathBuf) -> Result { let mut mtx = self.backend().lock().expect("Locking Mutex failed"); let backend = mtx.get_mut(); Ok(backend.contains_key(pb)) } - fn is_file(&self, pb: &PathBuf) -> Result { + fn is_file(&self, pb: &PathBuf) -> Result { // Because we only store Entries in the memory-internal backend, we only have to check for // existance here, as if a path exists in the inmemory storage, it is always mapped to an // entry. hence it is always a path to a file @@ -165,13 +168,15 @@ impl FileAbstraction for InMemoryFileAbstraction { Box::new(InMemoryFileAbstractionInstance::new(self.backend().clone(), p)) } - fn drain(&self) -> Result { + fn drain(&self) -> Result { self.backend_cloned().map(Drain::new) } - fn fill<'a>(&'a mut self, mut d: Drain) -> Result<(), SE> { + fn fill<'a>(&'a mut self, mut d: Drain) -> Result<()> { debug!("Draining into : {:?}", self); - let mut mtx = self.backend().lock().map_err(|_| SEK::LockError)?; + let mut mtx = self.backend() + .lock() + .map_err(|_| EM::LockError)?; let backend = mtx.get_mut(); for (path, element) in d.iter() { @@ -182,17 +187,17 @@ impl FileAbstraction for InMemoryFileAbstraction { Ok(()) } - fn pathes_recursively(&self, _basepath: PathBuf, storepath: PathBuf, backend: Arc) -> Result { + fn pathes_recursively(&self, _basepath: PathBuf, storepath: PathBuf, backend: Arc) -> Result { trace!("Building PathIterator object (inmemory implementation)"); let keys : Vec = self .backend() .lock() - .map_err(|_| SE::from_kind(SEK::FileError))? + .map_err(|_| EM::LockError)? .get_mut() .keys() .map(PathBuf::from) .map(Ok) - .collect::>()?; // we have to collect() because of the lock() above. + .collect::>()?; // we have to collect() because of the lock() above. Ok(PathIterator::new(Box::new(InMemPathIterBuilder(keys)), storepath, backend)) } @@ -201,7 +206,7 @@ impl FileAbstraction for InMemoryFileAbstraction { pub(crate) struct InMemPathIterBuilder(Vec); impl PathIterBuilder for InMemPathIterBuilder { - fn build_iter(&self) -> Box>> { + fn build_iter(&self) -> Box>> { Box::new(self.0.clone().into_iter().map(Ok)) } diff --git a/lib/core/libimagstore/src/file_abstraction/iter.rs b/lib/core/libimagstore/src/file_abstraction/iter.rs index 4c5dcd4e..82edf41a 100644 --- a/lib/core/libimagstore/src/file_abstraction/iter.rs +++ b/lib/core/libimagstore/src/file_abstraction/iter.rs @@ -20,7 +20,8 @@ use std::path::PathBuf; use std::sync::Arc; -use error::Result; +use failure::Fallible as Result; + use storeid::StoreId; use file_abstraction::FileAbstraction; diff --git a/lib/core/libimagstore/src/file_abstraction/mod.rs b/lib/core/libimagstore/src/file_abstraction/mod.rs index 5e50db55..3de47f0a 100644 --- a/lib/core/libimagstore/src/file_abstraction/mod.rs +++ b/lib/core/libimagstore/src/file_abstraction/mod.rs @@ -22,7 +22,8 @@ use std::fmt::Debug; use std::collections::HashMap; use std::sync::Arc; -use error::StoreError as SE; +use failure::Fallible as Result; + use store::Entry; use storeid::StoreId; @@ -38,20 +39,20 @@ use self::iter::PathIterator; /// An abstraction trait over filesystem actions pub trait FileAbstraction : Debug { - fn remove_file(&self, path: &PathBuf) -> Result<(), SE>; - fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE>; - fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<(), SE>; - fn create_dir_all(&self, _: &PathBuf) -> Result<(), SE>; + fn remove_file(&self, path: &PathBuf) -> Result<()>; + fn copy(&self, from: &PathBuf, to: &PathBuf) -> Result<()>; + fn rename(&self, from: &PathBuf, to: &PathBuf) -> Result<()>; + fn create_dir_all(&self, _: &PathBuf) -> Result<()>; - fn exists(&self, &PathBuf) -> Result; - fn is_file(&self, &PathBuf) -> Result; + fn exists(&self, &PathBuf) -> Result; + fn is_file(&self, &PathBuf) -> Result; fn new_instance(&self, p: PathBuf) -> Box; - fn drain(&self) -> Result; - fn fill<'a>(&'a mut self, d: Drain) -> Result<(), SE>; + fn drain(&self) -> Result; + fn fill<'a>(&'a mut self, d: Drain) -> Result<()>; - fn pathes_recursively(&self, basepath: PathBuf, storepath: PathBuf, backend: Arc) -> Result; + fn pathes_recursively(&self, basepath: PathBuf, storepath: PathBuf, backend: Arc) -> Result; } /// An abstraction trait over actions on files @@ -61,8 +62,8 @@ pub trait FileAbstractionInstance : Debug { /// /// The `StoreId` is passed because the backend does not know where the Entry lives, but the /// Entry type itself must be constructed with the id. - fn get_file_content(&mut self, id: StoreId) -> Result; - fn write_file_content(&mut self, buf: &Entry) -> Result<(), SE>; + fn get_file_content(&mut self, id: StoreId) -> Result>; + fn write_file_content(&mut self, buf: &Entry) -> Result<()>; } pub struct Drain(HashMap); @@ -119,7 +120,7 @@ version = "{}" Hello World"#, env!("CARGO_PKG_VERSION"))).unwrap(); lf.write_file_content(&file).unwrap(); - let bah = lf.get_file_content(loca).unwrap(); + let bah = lf.get_file_content(loca).unwrap().unwrap(); assert_eq!(bah.get_content(), "Hello World"); } @@ -140,7 +141,7 @@ Hello World baz"#, env!("CARGO_PKG_VERSION"))).unwrap(); lf.write_file_content(&file).unwrap(); - let bah = lf.get_file_content(loca).unwrap(); + let bah = lf.get_file_content(loca).unwrap().unwrap(); assert_eq!(bah.get_content(), "Hello World\nbaz"); } @@ -163,7 +164,7 @@ baz "#, env!("CARGO_PKG_VERSION"))).unwrap(); lf.write_file_content(&file).unwrap(); - let bah = lf.get_file_content(loca).unwrap(); + let bah = lf.get_file_content(loca).unwrap().unwrap(); assert_eq!(bah.get_content(), "Hello World\nbaz\n\n"); } diff --git a/lib/core/libimagstore/src/iter.rs b/lib/core/libimagstore/src/iter.rs index d2fd1a16..b931a7d6 100644 --- a/lib/core/libimagstore/src/iter.rs +++ b/lib/core/libimagstore/src/iter.rs @@ -31,41 +31,34 @@ macro_rules! mk_iterator_mod { #[allow(unused_imports)] use store::FileLockEntry; use store::Store; - use error::StoreError; - use std::result::Result as RResult; + use failure::Fallible as Result; - pub struct $itername<'a, E>(Box> + 'a>, &'a Store) - where E: From; + pub struct $itername<'a>(Box> + 'a>, &'a Store); - impl<'a, E> $itername<'a, E> - where E: From + impl<'a> $itername<'a> { - pub fn new(inner: Box> + 'a>, store: &'a Store) -> Self { + pub fn new(inner: Box> + 'a>, store: &'a Store) -> Self { $itername(inner, store) } } - impl<'a, E> Iterator for $itername<'a, E> - where E: From + impl<'a> Iterator for $itername<'a> { - type Item = RResult<$yield, E>; + type Item = Result<$yield>; fn next(&mut self) -> Option { - self.0.next().map(|id| $fun(id?, self.1).map_err(E::from)) + self.0.next().map(|id| $fun(id?, self.1)) } } - pub trait $extname<'a, E> - where E: From - { - fn $extfnname(self, store: &'a Store) -> $itername<'a, E>; + pub trait $extname<'a> { + fn $extfnname(self, store: &'a Store) -> $itername<'a>; } - impl<'a, I, E> $extname<'a, E> for I - where I: Iterator> + 'a, - E: From + impl<'a, I> $extname<'a> for I + where I: Iterator> + 'a { - fn $extfnname(self, store: &'a Store) -> $itername<'a, E> { + fn $extfnname(self, store: &'a Store) -> $itername<'a> { $itername(Box::new(self), store) } } @@ -151,8 +144,7 @@ use self::get::StoreGetIterator; use self::retrieve::StoreRetrieveIterator; use file_abstraction::iter::PathIterator; use store::Store; -use error::StoreError; -use error::Result; +use failure::Fallible as Result; /// Iterator for iterating over all (or a subset of all) entries /// @@ -194,21 +186,21 @@ impl<'a> Entries<'a> { /// Transform the iterator into a StoreDeleteIterator /// /// This immitates the API from `libimagstore::iter`. - pub fn into_delete_iter(self) -> StoreDeleteIterator<'a, StoreError> { + pub fn into_delete_iter(self) -> StoreDeleteIterator<'a> { StoreDeleteIterator::new(Box::new(self.0), self.1) } /// Transform the iterator into a StoreGetIterator /// /// This immitates the API from `libimagstore::iter`. - pub fn into_get_iter(self) -> StoreGetIterator<'a, StoreError> { + pub fn into_get_iter(self) -> StoreGetIterator<'a> { StoreGetIterator::new(Box::new(self.0), self.1) } /// Transform the iterator into a StoreRetrieveIterator /// /// This immitates the API from `libimagstore::iter`. - pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a, StoreError> { + pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a> { StoreRetrieveIterator::new(Box::new(self.0), self.1) } diff --git a/lib/core/libimagstore/src/lib.rs b/lib/core/libimagstore/src/lib.rs index 0d6f0ccb..3fc544b6 100644 --- a/lib/core/libimagstore/src/lib.rs +++ b/lib/core/libimagstore/src/lib.rs @@ -44,7 +44,7 @@ extern crate semver; extern crate walkdir; #[macro_use] extern crate is_match; extern crate serde_json; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; extern crate toml_query; extern crate libimagerror; @@ -53,7 +53,6 @@ extern crate libimagutil; #[macro_use] mod util; pub mod storeid; -pub mod error; pub mod iter; pub mod store; mod configuration; diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs index 36532cec..1828e7f3 100644 --- a/lib/core/libimagstore/src/store.rs +++ b/lib/core/libimagstore/src/store.rs @@ -31,12 +31,16 @@ use std::fmt::Formatter; use std::fmt::Debug; use std::fmt::Error as FMTError; +use libimagerror::errors::ErrorMsg as EM; + use toml::Value; use toml_query::read::TomlValueReadExt; use toml_query::read::TomlValueReadTypeExt; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::err_msg; +use failure::Error; -use error::{StoreError as SE, StoreErrorKind as SEK}; -use error::ResultExt; use storeid::{IntoStoreId, StoreId}; use iter::Entries; use file_abstraction::FileAbstractionInstance; @@ -48,9 +52,6 @@ pub use file_abstraction::InMemoryFileAbstraction; use libimagutil::debug_result::*; -/// The Result Type returned by any interaction with the store that could fail -pub type Result = RResult; - #[derive(Debug, PartialEq)] enum StoreEntryStatus { @@ -76,7 +77,7 @@ impl StoreEntry { { open_file(pb.clone()) .and_then(|f| f.lock_exclusive()) - .chain_err(|| SEK::IoError)?; + .with_context(|| EM::IO)?; } Ok(StoreEntry { @@ -94,15 +95,12 @@ impl StoreEntry { fn get_entry(&mut self) -> Result { if !self.is_borrowed() { - self.file - .get_file_content(self.id.clone()) - .or_else(|err| if is_match!(err.kind(), &SEK::FileNotFound) { - Ok(Entry::new(self.id.clone())) - } else { - Err(err) - }) + match self.file.get_file_content(self.id.clone())? { + Some(file) => Ok(file), + None => Ok(Entry::new(self.id.clone())) + } } else { - Err(SE::from_kind(SEK::EntryAlreadyBorrowed(self.id.clone()))) + Err(format_err!("EntryAlreadyBorrowed: {}", self.id)) } } @@ -184,18 +182,19 @@ impl Store { debug!("Building new Store object"); if !location.exists() { if !config_implicit_store_create_allowed(store_config)? { - return Err(SE::from_kind(SEK::CreateStoreDirDenied)) - .chain_err(|| SEK::FileError) - .chain_err(|| SEK::IoError); + return Err(format_err!("CreateStoreDirDenied")) + .context(EM::FileError) + .context(EM::IO) + .map_err(Error::from) } backend .create_dir_all(&location) - .chain_err(|| SEK::StorePathCreate(location.clone())) + .context(format_err!("StorePathCreate: {}", location.display())) .map_dbg_err_str("Failed")?; } else if location.is_file() { debug!("Store path exists as file"); - return Err(SE::from_kind(SEK::StorePathExists(location))); + return Err(format_err!("StorePathExists: {}", location.display())); } let store = Store { @@ -218,45 +217,34 @@ impl Store { /// /// On success: FileLockEntry /// - /// On error: - /// - Errors StoreId::into_storeid() might return - /// - EntryAlreadyExists(id) if the entry exists - /// - CreateCallError(LockPoisoned()) if the internal lock is poisened. - /// - CreateCallError(EntryAlreadyExists()) if the entry exists already. - /// pub fn create<'a, S: IntoStoreId>(&'a self, id: S) -> Result> { let id = id.into_storeid()?.with_base(self.path().clone()); debug!("Creating id: '{}'", id); - let exists = self.entries + let exists = id.exists()? || self.entries .read() - .map_err(|_| SE::from_kind(SEK::LockPoisoned)) .map(|map| map.contains_key(&id)) - .and_then(|exists| if exists { - Ok(exists) - } else { - let pb = id.clone().into_pathbuf().map_err(SE::from)?; - self.backend.exists(&pb) - }) - .chain_err(|| SEK::CreateCallError(id.clone()))?; + .map_err(|_| Error::from(EM::LockError)) + .context(format_err!("CreateCallError: {}", id))?; if exists { debug!("Entry exists: {:?}", id); - return Err(SEK::EntryAlreadyExists(id).into()); + return Err(format_err!("EntryAlreadyExists: {}", id)); } { let mut hsmap = self .entries .write() - .map_err(|_| SE::from_kind(SEK::LockPoisoned)) - .chain_err(|| SEK::CreateCallError(id.clone()))?; + .map_err(|_| Error::from(EM::LockError)) + .context(format_err!("CreateCallError: {}", id))?; if hsmap.contains_key(&id) { debug!("Cannot create, internal cache already contains: '{}'", id); - return Err(SE::from_kind(SEK::EntryAlreadyExists(id.clone()))) - .chain_err(|| SEK::CreateCallError(id.clone())); + return Err(format_err!("EntryAlreadyExists: {}", id)) + .context(format_err!("CreateCallError: {}", id)) + .map_err(Error::from) } hsmap.insert(id.clone(), { debug!("Creating: '{}'", id); @@ -281,17 +269,13 @@ impl Store { /// /// On success: FileLockEntry /// - /// On error: - /// - Errors StoreId::into_storeid() might return - /// - RetrieveCallError(LockPoisoned()) if the internal lock is poisened. - /// pub fn retrieve<'a, S: IntoStoreId>(&'a self, id: S) -> Result> { let id = id.into_storeid()?.with_base(self.path().clone()); debug!("Retrieving id: '{}'", id); let entry = self .entries .write() - .map_err(|_| SE::from_kind(SEK::LockPoisoned)) + .map_err(|_| Error::from(EM::LockError)) .and_then(|mut es| { let new_se = StoreEntry::new(id.clone(), &self.backend)?; let se = es.entry(id.clone()).or_insert(new_se); @@ -299,7 +283,7 @@ impl Store { se.status = StoreEntryStatus::Borrowed; entry }) - .chain_err(|| SEK::RetrieveCallError(id.clone()))?; + .context(format_err!("RetrieveCallError: {}", id))?; debug!("Constructing FileLockEntry: '{}'", id); Ok(FileLockEntry::new(self, entry)) @@ -320,24 +304,21 @@ impl Store { debug!("Getting id: '{}'", id); - let exists = self.entries + let exists = id.exists()? || self.entries .read() - .map_err(|_| SE::from_kind(SEK::LockPoisoned)) .map(|map| map.contains_key(&id)) - .and_then(|exists| if exists { - Ok(exists) - } else { - let pb = id.clone().into_pathbuf().map_err(SE::from)?; - self.backend.exists(&pb) - }) - .chain_err(|| SEK::GetCallError(id.clone()))?; + .map_err(|_| Error::from(EM::LockError)) + .context(format_err!("GetCallError: {}", id))?; if !exists { debug!("Does not exist in internal cache or filesystem: {:?}", id); return Ok(None); } - self.retrieve(id.clone()).map(Some).chain_err(|| SEK::GetCallError(id)) + self.retrieve(id.clone()) + .map(Some) + .context(format_err!("GetCallError: {}", id)) + .map_err(Error::from) } /// Write (update) the `FileLockEntry` to disk @@ -346,15 +327,11 @@ impl Store { /// /// On success: Entry /// - /// On error: - /// - UpdateCallError(LockPoisoned()) if the internal write lock cannot be aquierd. - /// - IdNotFound() if the entry was not found in the stor - /// - Errors Entry::verify() might return - /// - Errors StoreEntry::write_entry() might return - /// pub fn update<'a>(&'a self, entry: &mut FileLockEntry<'a>) -> Result<()> { debug!("Updating FileLockEntry at '{}'", entry.get_location()); - self._update(entry, false).chain_err(|| SEK::UpdateCallError(entry.get_location().clone())) + self._update(entry, false) + .context(format_err!("UpdateCallError: {}", entry.get_location())) + .map_err(Error::from) } /// Internal method to write to the filesystem store. @@ -365,10 +342,11 @@ impl Store { /// it is not public. /// fn _update<'a>(&'a self, entry: &mut FileLockEntry<'a>, modify_presence: bool) -> Result<()> { - let mut hsmap = self.entries.write().map_err(|_| SE::from_kind(SEK::LockPoisoned))?; + let mut hsmap = self.entries.write() + .map_err(|_| Error::from(EM::LockError))?; let se = hsmap.get_mut(&entry.location).ok_or_else(|| { - SE::from_kind(SEK::IdNotFound(entry.location.clone())) + EM::EntryNotFound(entry.location.local_display_string()) })?; assert!(se.is_borrowed(), "Tried to update a non borrowed entry."); @@ -401,7 +379,8 @@ impl Store { pub fn flush_cache(&self) -> Result<()> { // We borrow this early so that between the aggregation of the flushables and the actual // flush, there is no borrowing from the store. - let mut hsmap = self.entries.write().map_err(|_| SE::from_kind(SEK::LockPoisoned))?; + let mut hsmap = self.entries.write() + .map_err(|_| Error::from(EM::LockError))?; let mut to_flush = vec![]; for (storeid, se) in hsmap.deref() { @@ -421,37 +400,34 @@ impl Store { /// The number of elements in the internal cache pub fn cache_size(&self) -> Result { - let hsmap = self.entries.read().map_err(|_| SE::from_kind(SEK::LockPoisoned))?; + let hsmap = self.entries.read().map_err(|_| Error::from(EM::LockError))?; Ok(hsmap.iter().count()) } /// The size of the internal cache pub fn cache_capacity(&self) -> Result { - let hsmap = self.entries.read().map_err(|_| SE::from_kind(SEK::LockPoisoned))?; + let hsmap = self.entries.read().map_err(|_| Error::from(EM::LockError))?; Ok(hsmap.capacity()) } - /// Get a copy of a given entry, this cannot be used to mutate the one on disk + // Get a copy of a given entry, this cannot be used to mutate the one on disk /// /// # Return value /// /// On success: Entry /// - /// On error: - /// - RetrieveCopyCallError(LockPoisoned()) if the internal write lock cannot be aquierd. - /// - RetrieveCopyCallError(IdLocked()) if the Entry is borrowed currently - /// - Errors StoreEntry::new() might return - /// pub fn get_copy(&self, id: S) -> Result { let id = id.into_storeid()?.with_base(self.path().clone()); debug!("Retrieving copy of '{}'", id); let entries = self.entries.write() - .map_err(|_| SE::from_kind(SEK::LockPoisoned)) - .chain_err(|| SEK::RetrieveCopyCallError(id.clone()))?; + .map_err(|_| Error::from(EM::LockError)) + .context(format_err!("RetrieveCopyCallError: {}", id))?; // if the entry is currently modified by the user, we cannot drop it if entries.get(&id).map(|e| e.is_borrowed()).unwrap_or(false) { - return Err(SE::from_kind(SEK::IdLocked)).chain_err(|| SEK::RetrieveCopyCallError(id)); + return Err(EM::IdLocked) + .context(format_err!("RetrieveCopyCallError: {}", id)) + .map_err(Error::from) } StoreEntry::new(id, &self.backend)?.get_entry() @@ -463,27 +439,29 @@ impl Store { /// /// On success: () /// - /// On error: - /// - DeleteCallError(LockPoisoned()) if the internal write lock cannot be aquierd. - /// - DeleteCallError(FileNotFound()) if the StoreId refers to a non-existing entry. - /// - DeleteCallError(FileError()) if the internals failed to remove the file. - /// pub fn delete(&self, id: S) -> Result<()> { let id = id.into_storeid()?.with_base(self.path().clone()); debug!("Deleting id: '{}'", id); + // Small optimization: We need the pathbuf for deleting, but when calling + // StoreId::exists(), a PathBuf object gets allocated. So we simply get a + // PathBuf here, check whether it is there and if it is, we can re-use it to + // delete the filesystem file. let pb = id.clone().into_pathbuf()?; + { let mut entries = self .entries .write() - .map_err(|_| SE::from_kind(SEK::LockPoisoned)) - .chain_err(|| SEK::DeleteCallError(id.clone()))?; + .map_err(|_| Error::from(EM::LockError)) + .context(format_err!("DeleteCallError: {}", id))?; let do_remove = match entries.get(&id) { Some(e) => if e.is_borrowed() { // entry is currently borrowed, we cannot delete it - return Err(SE::from_kind(SEK::IdLocked)).chain_err(|| SEK::DeleteCallError(id)); + return Err(Error::from(EM::LockError)) + .context(format_err!("DeleteCallError: {}", id)) + .map_err(Error::from) // false } else { // Entry is in the cache // Remove Entry from the cache @@ -496,8 +474,9 @@ impl Store { if !self.backend.exists(&pb)? { debug!("Seems like {:?} is not even on the FS", pb); - return Err(SE::from_kind(SEK::FileNotFound)) - .chain_err(|| SEK::DeleteCallError(id)) + return Err(EM::FileNotFound) + .context(format_err!("DeleteCallError: {}", id)) + .map_err(Error::from) } // else { continue } false @@ -513,8 +492,8 @@ impl Store { let _ = self .backend .remove_file(&pb) - .chain_err(|| SEK::FileError) - .chain_err(|| SEK::DeleteCallError(id))?; + .context(EM::FileError) + .context(format_err!("DeleteCallError: {}", id))?; debug!("Deleted"); Ok(()) @@ -540,12 +519,13 @@ impl Store { let hsmap = self .entries .write() - .map_err(|_| SE::from_kind(SEK::LockPoisoned)) - .chain_err(|| SEK::MoveCallError(entry.get_location().clone(), new_id.clone()))?; + .map_err(|_| Error::from(EM::LockError)) + .context(format_err!("MoveCallError: {} -> {}", entry.get_location(), new_id))?; if hsmap.contains_key(&new_id) { - return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone()))) - .chain_err(|| SEK::MoveCallError(entry.get_location().clone(), new_id.clone())) + return Err(format_err!("Entry exists already: {}", new_id.clone())) + .context(format_err!("MoveCallError: {} -> {}", entry.get_location(), new_id)) + .map_err(Error::from) } let old_id = entry.get_location().clone(); @@ -560,8 +540,9 @@ impl Store { } else { Ok(()) }) - .chain_err(|| SEK::FileError) - .chain_err(|| SEK::MoveCallError(old_id, new_id)) + .context(EM::FileError) + .context(format_err!("MoveCallError: {} -> {}", old_id, new_id)) + .map_err(Error::from) } /// Move an entry without loading @@ -604,10 +585,11 @@ impl Store { debug!("Moving '{}' to '{}'", old_id, new_id); { - let mut hsmap = self.entries.write().map_err(|_| SE::from_kind(SEK::LockPoisoned))?; + let mut hsmap = self.entries.write() + .map_err(|_| Error::from(EM::LockError))?; if hsmap.contains_key(&new_id) { - return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone()))); + return Err(format_err!("Entry already exists: {}", new_id)); } debug!("New id does not exist in cache"); @@ -615,7 +597,7 @@ impl Store { // if we have one, but it is borrowed, we really should not rename it, as this might // lead to strange errors if hsmap.get(&old_id).map(|e| e.is_borrowed()).unwrap_or(false) { - return Err(SE::from_kind(SEK::EntryAlreadyBorrowed(old_id.clone()))); + return Err(format_err!("Entry already borrowed: {}", old_id)); } debug!("Old id is not yet borrowed"); @@ -624,14 +606,18 @@ impl Store { let new_id_pb = new_id.clone().with_base(self.path().clone()).into_pathbuf()?; if self.backend.exists(&new_id_pb)? { - return Err(SE::from_kind(SEK::EntryAlreadyExists(new_id.clone()))); + return Err(format_err!("Entry already exists: {}", new_id)); } debug!("New entry does not yet exist on filesystem. Good."); let _ = self .backend .rename(&old_id_pb, &new_id_pb) - .chain_err(|| SEK::EntryRenameError(old_id_pb, new_id_pb))?; + .context({ + let old = old_id_pb.display().to_string(); + let new = new_id_pb.display().to_string(); + format_err!("Rename error: {} -> {}", old, new) + })?; debug!("Rename worked on filesystem"); @@ -792,7 +778,7 @@ impl Entry { pub fn from_reader(loc: S, file: &mut Read) -> Result { let text = { let mut s = String::new(); - file.read_to_string(&mut s)?; + file.read_to_string(&mut s).context(EM::IO)?; s }; Self::from_str(loc, &text[..]) @@ -828,7 +814,9 @@ impl Entry { /// disk). pub fn to_str(&self) -> Result { Ok(format!("---\n{header}---\n{content}", - header = ::toml::ser::to_string_pretty(&self.header)?, + header = ::toml::ser::to_string_pretty(&self.header) + .map_err(Error::from) + .context(err_msg("TOML Error"))?, content = self.content)) } @@ -872,12 +860,12 @@ impl Entry { /// Currently, this only verifies the header. This might change in the future. pub fn verify(&self) -> Result<()> { if !has_main_section(&self.header)? { - Err(SE::from_kind(SEK::MissingMainSection)) + Err(format_err!("MissingMainSection")) } else if !has_imag_version_in_main_section(&self.header)? { - Err(SE::from_kind(SEK::MissingVersionInfo)) + Err(format_err!("MissingVersionInfo")) } else if !has_only_tables(&self.header)? { debug!("Could not verify that it only has tables in its base table"); - Err(SE::from_kind(SEK::NonTableInBaseTable)) + Err(format_err!("NonTableInBaseTable")) } else { Ok(()) } @@ -899,21 +887,26 @@ fn has_only_tables(t: &Value) -> Result { debug!("Verifying that table has only tables"); match *t { Value::Table(ref tab) => Ok(tab.iter().all(|(_, x)| is_match!(*x, Value::Table(_)))), - _ => Err(SE::from_kind(SEK::HeaderTypeFailure)), + _ => Err(format_err!("HeaderTypeFailure")), } } fn has_main_section(t: &Value) -> Result { - t.read("imag")? - .ok_or_else(|| SE::from_kind(SEK::ConfigKeyMissingError("imag"))) + t.read("imag") + .map_err(Error::from) + .context(EM::TomlQueryError)? + .ok_or_else(|| format_err!("ConfigKeyMissingError('imag')")) .map(Value::is_table) } fn has_imag_version_in_main_section(t: &Value) -> Result { - t.read_string("imag.version")? - .ok_or_else(|| SE::from_kind(SEK::ConfigKeyMissingError("imag.version"))) + t.read_string("imag.version") + .map_err(Error::from) + .context(EM::TomlQueryError)? + .ok_or_else(|| format_err!("ConfigKeyMissingError('imag.version')")) + .map_err(Error::from) .map(String::from) - .map(|s| ::semver::Version::parse(&s).is_ok()) + .map(|s: String| ::semver::Version::parse(&s).is_ok()) } @@ -1095,14 +1088,12 @@ mod store_tests { #[test] fn test_store_create_twice() { - use error::StoreErrorKind as SEK; let store = get_store(); for n in 1..100 { let s = format!("test-{}", n % 50); store.create(PathBuf::from(s.clone())) - .map_err(|e| assert!(is_match!(e.kind(), &SEK::EntryAlreadyExists(_)) && n >= 50)) .ok() .map(|entry| { assert!(entry.verify().is_ok()); @@ -1190,8 +1181,8 @@ mod store_tests { assert!(store.create(id.clone()).is_ok()); } - let id_with_base = id.clone().with_base(store.path().clone()); { + let id_with_base = id.clone().with_base(store.path().clone()); assert!(store.entries.read().unwrap().get(&id_with_base).is_some()); } @@ -1203,16 +1194,8 @@ mod store_tests { assert!(store.entries.read().unwrap().get(&id_mv_with_base).is_some()); } - { - let pb = id_with_base.into_pathbuf().unwrap(); - let exists = store.backend.exists(&pb).unwrap(); - assert!(!exists, "Old entry exists in Filesystem, but shouldn't"); - } - - let result = store.get(id.clone()); - - assert!(match result { Ok(None) => true, _ => false }, - "Moved id ({:?}) is still there: {:?}", id, result); + assert!(match store.get(id.clone()) { Ok(None) => true, _ => false }, + "Moved id ({:?}) is still there", id); assert!(match store.get(id_mv.clone()) { Ok(Some(_)) => true, _ => false }, "New id ({:?}) is not in store...", id_mv); } diff --git a/lib/core/libimagstore/src/storeid.rs b/lib/core/libimagstore/src/storeid.rs index 38aa0f3c..5a2fe754 100644 --- a/lib/core/libimagstore/src/storeid.rs +++ b/lib/core/libimagstore/src/storeid.rs @@ -26,10 +26,11 @@ use std::fmt::Error as FmtError; use std::result::Result as RResult; use std::path::Components; -use error::StoreErrorKind as SEK; -use error::StoreError as SE; -use error::ResultExt; -use store::Result; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::err_msg; +use failure::Error; + use store::Store; use iter::create::StoreCreateIterator; @@ -64,14 +65,13 @@ impl StoreId { /// /// Automatically creates a StoreId object which has a `base` set to `store_part` if stripping /// the `store_part` from the `full_path` succeeded. - /// - /// Returns a `StoreErrorKind::StoreIdBuildFromFullPathError` if stripping failes. pub fn from_full_path(store_part: &PathBuf, full_path: D) -> Result where D: Deref { let p = full_path .strip_prefix(store_part) - .chain_err(|| SEK::StoreIdBuildFromFullPathError)?; + .map_err(Error::from) + .context(err_msg("Error building Store Id from full path"))?; StoreId::new(Some(store_part.clone()), PathBuf::from(p)) } @@ -79,7 +79,7 @@ impl StoreId { debug!("Trying to get a new baseless id from: {:?}", id); if id.is_absolute() { debug!("Error: Id is absolute!"); - Err(SE::from_kind(SEK::StoreIdLocalPartAbsoluteError(id))) + Err(format_err!("Store Id local part is absolute: {}", id.display())) } else { debug!("Building Storeid object baseless"); Ok(StoreId { @@ -103,7 +103,9 @@ impl StoreId { /// specified. pub fn into_pathbuf(mut self) -> Result { let base = self.base.take(); - let mut base = base.ok_or_else(|| SEK::StoreIdHasNoBaseError(self.id.clone()))?; + let mut base = base.ok_or_else(|| { + format_err!("Store Id has no base: {:?}", self.id.display().to_string()) + })?; base.push(self.id); Ok(base) } @@ -125,7 +127,8 @@ impl StoreId { .unwrap_or_else(|| self.id.clone()) .to_str() .map(String::from) - .ok_or_else(|| SE::from_kind(SEK::StoreIdHandlingError)) + .ok_or_else(|| err_msg("Store ID Handling error")) + .map_err(Error::from) } /// Helper function for creating a displayable String from StoreId @@ -232,7 +235,7 @@ macro_rules! module_entry_path_mod { use std::path::PathBuf; use $crate::storeid::StoreId; - use $crate::store::Result; + use failure::Fallible as Result; /// A Struct giving you the ability to choose store entries assigned /// to it. @@ -313,8 +316,6 @@ impl<'a> Iterator for StoreIdIteratorWithStore<'a> { } } -use error::StoreError; - impl<'a> StoreIdIteratorWithStore<'a> { pub fn new(iter: Box>>, store: &'a Store) -> Self { @@ -328,7 +329,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// Transform the iterator into a StoreCreateIterator /// /// This immitates the API from `libimagstore::iter`. - pub fn into_create_iter(self) -> StoreCreateIterator<'a, StoreError> { + pub fn into_create_iter(self) -> StoreCreateIterator<'a> { StoreCreateIterator::new(Box::new(self.0), self.1) } @@ -336,7 +337,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// /// /// This immitates the API from `libimagstore::iter`. - pub fn into_delete_iter(self) -> StoreDeleteIterator<'a, StoreError> { + pub fn into_delete_iter(self) -> StoreDeleteIterator<'a> { StoreDeleteIterator::new(Box::new(self.0), self.1) } @@ -344,7 +345,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// /// /// This immitates the API from `libimagstore::iter`. - pub fn into_get_iter(self) -> StoreGetIterator<'a, StoreError> { + pub fn into_get_iter(self) -> StoreGetIterator<'a> { StoreGetIterator::new(Box::new(self.0), self.1) } @@ -352,7 +353,7 @@ impl<'a> StoreIdIteratorWithStore<'a> { /// /// /// This immitates the API from `libimagstore::iter`. - pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a, StoreError> { + pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a> { StoreRetrieveIterator::new(Box::new(self.0), self.1) } @@ -364,7 +365,6 @@ mod test { use storeid::StoreId; use storeid::IntoStoreId; - use error::StoreErrorKind as SEK; module_entry_path_mod!("test"); @@ -444,8 +444,6 @@ mod test { let pb = id.unwrap().into_pathbuf(); assert!(pb.is_err()); - - assert!(is_match!(pb.unwrap_err().kind(), &SEK::StoreIdHasNoBaseError(_))); } #[test] diff --git a/lib/core/libimagstore/src/util.rs b/lib/core/libimagstore/src/util.rs index 6d7d4786..e19fcc19 100644 --- a/lib/core/libimagstore/src/util.rs +++ b/lib/core/libimagstore/src/util.rs @@ -20,8 +20,10 @@ use std::fmt::Write; use toml::Value; +use failure::Fallible as Result; +use failure::ResultExt; -use store::Result; +use libimagerror::errors::ErrorMsg as EM; #[cfg(feature = "early-panic")] #[macro_export] @@ -40,6 +42,7 @@ macro_rules! if_cfg_panic { } pub fn entry_buffer_to_header_content(buf: &str) -> Result<(Value, String)> { + debug!("Building entry from string"); let mut header = String::new(); let mut content = String::new(); @@ -52,15 +55,16 @@ pub fn entry_buffer_to_header_content(buf: &str) -> Result<(Value, String)> { header_consumed = true; // do not further process the line } else if !header_consumed { - let _ = writeln!(header, "{}", line)?; + let _ = writeln!(header, "{}", line).context(EM::FormatError)?; } else if iter.peek().is_some() { - let _ = writeln!(content, "{}", line)?; + let _ = writeln!(content, "{}", line).context(EM::FormatError)?; } else { - let _ = write!(content, "{}", line)?; + let _ = write!(content, "{}", line).context(EM::FormatError)?; } } - ::toml::de::from_str(&header).map_err(From::from).map(|h| (h, content)) + let h = ::toml::de::from_str(&header).context(EM::TomlDeserError)?; + Ok((h, content)) } #[cfg(test)] diff --git a/lib/domain/libimagbookmark/Cargo.toml b/lib/domain/libimagbookmark/Cargo.toml index e93e7362..c380fe01 100644 --- a/lib/domain/libimagbookmark/Cargo.toml +++ b/lib/domain/libimagbookmark/Cargo.toml @@ -22,7 +22,7 @@ maintenance = { status = "actively-developed" } [dependencies] url = "1.5" regex = "1" -error-chain = "0.12" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/domain/libimagbookmark/src/collection.rs b/lib/domain/libimagbookmark/src/collection.rs index d5e0b2d7..22333690 100644 --- a/lib/domain/libimagbookmark/src/collection.rs +++ b/lib/domain/libimagbookmark/src/collection.rs @@ -26,7 +26,8 @@ use regex::Regex; -use error::Result; +use failure::Fallible as Result; +use failure::Error; use module_path::ModuleEntryPath; use libimagstore::store::Store; @@ -53,22 +54,22 @@ impl<'a> BookmarkCollectionStore<'a> for Store { fn new(&'a self, name: &str) -> Result> { ModuleEntryPath::new(name) .into_storeid() - .and_then(|id| self.create(id).map_err(From::from)) - .map_err(From::from) + .and_then(|id| self.create(id).map_err(Error::from)) + .map_err(Error::from) } fn get(&'a self, name: &str) -> Result>> { ModuleEntryPath::new(name) .into_storeid() - .and_then(|id| self.get(id).map_err(From::from)) - .map_err(From::from) + .and_then(|id| self.get(id).map_err(Error::from)) + .map_err(Error::from) } fn delete(&'a self, name: &str) -> Result<()> { ModuleEntryPath::new(name) .into_storeid() - .and_then(|id| self.delete(id).map_err(From::from)) - .map_err(From::from) + .and_then(|id| self.delete(id).map_err(Error::from)) + .map_err(Error::from) } } @@ -84,47 +85,35 @@ pub trait BookmarkCollection : Sized + InternalLinker + ExternalLinker { impl BookmarkCollection for Entry { fn links<'a>(&self, store: &'a Store) -> Result> { - self.get_external_links(store).map_err(From::from) + self.get_external_links(store) } fn link_entries(&self) -> Result> { use libimagentrylink::external::is_external_link_storeid; - - self.get_internal_links() - .map(|v| v.filter(|id| is_external_link_storeid(id)).collect()) - .map_err(From::from) + self.get_internal_links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect()) } fn add_link(&mut self, store: &Store, l: Link) -> Result<()> { use link::IntoUrl; - - l.into_url() - .and_then(|url| self.add_external_link(store, url).map_err(From::from)) - .map_err(From::from) + l.into_url().and_then(|url| self.add_external_link(store, url)) } fn get_links_matching<'a>(&self, store: &'a Store, r: Regex) -> Result> { use self::iter::IntoLinksMatchingRegexIter; - - self.get_external_links(store) - .map(|iter| iter.matching_regex(r)) - .map_err(From::from) + self.get_external_links(store).map(|iter| iter.matching_regex(r)) } fn remove_link(&mut self, store: &Store, l: Link) -> Result<()> { use link::IntoUrl; - - l.into_url() - .and_then(|url| self.remove_external_link(store, url).map_err(From::from)) - .map_err(From::from) + l.into_url().and_then(|url| self.remove_external_link(store, url)) } } pub mod iter { use link::Link; - use error::Result; - use error::BookmarkError as BE; + use failure::Fallible as Result; + use failure::Error; pub struct LinkIter(I) where I: Iterator; @@ -167,7 +156,7 @@ pub mod iter { loop { let n = match self.0.next() { Some(Ok(n)) => n, - Some(Err(e)) => return Some(Err(BE::from(e))), + Some(Err(e)) => return Some(Err(Error::from(e))), None => return None, }; diff --git a/lib/domain/libimagbookmark/src/error.rs b/lib/domain/libimagbookmark/src/error.rs deleted file mode 100644 index 49feefec..00000000 --- a/lib/domain/libimagbookmark/src/error.rs +++ /dev/null @@ -1,48 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - BookmarkError, BookmarkErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - LinkError(::libimagentrylink::error::LinkError, ::libimagentrylink::error::LinkErrorKind); - } - - errors { - LinkParsingError { - description("Link parsing error") - display("Link parsing error") - } - - LinkingError { - description("Error while linking") - display("Error while linking") - } - - CollectionNotFound { - description("Link-Collection not found") - display("Link-Collection not found") - } - - } -} - diff --git a/lib/domain/libimagbookmark/src/lib.rs b/lib/domain/libimagbookmark/src/lib.rs index b1623c01..0e89e20d 100644 --- a/lib/domain/libimagbookmark/src/lib.rs +++ b/lib/domain/libimagbookmark/src/lib.rs @@ -37,7 +37,7 @@ extern crate url; extern crate regex; -#[macro_use] extern crate error_chain; +extern crate failure; #[macro_use] extern crate libimagstore; extern crate libimagerror; @@ -46,5 +46,4 @@ extern crate libimagentrylink; module_entry_path_mod!("bookmark"); pub mod collection; -pub mod error; pub mod link; diff --git a/lib/domain/libimagbookmark/src/link.rs b/lib/domain/libimagbookmark/src/link.rs index 317e4767..f11035d1 100644 --- a/lib/domain/libimagbookmark/src/link.rs +++ b/lib/domain/libimagbookmark/src/link.rs @@ -19,7 +19,10 @@ use std::ops::{Deref, DerefMut}; -use error::Result; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; use url::Url; @@ -66,10 +69,7 @@ pub trait IntoUrl { impl IntoUrl for Link { fn into_url(self) -> Result { - use error::BookmarkErrorKind as BEK; - use error::ResultExt; - - Url::parse(&self[..]).chain_err(|| BEK::LinkParsingError) + Url::parse(&self[..]).context(err_msg("Link parsing error")).map_err(Error::from) } } diff --git a/lib/domain/libimagcontact/Cargo.toml b/lib/domain/libimagcontact/Cargo.toml index be76211c..7a88f45d 100644 --- a/lib/domain/libimagcontact/Cargo.toml +++ b/lib/domain/libimagcontact/Cargo.toml @@ -20,11 +20,11 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } maintenance = { status = "actively-developed" } [dependencies] -error-chain = "0.12" +failure = "0.1" log = "0.4" toml = "0.4" -toml-query = "0.7" -vobject = { git = "https://github.com/matthiasbeyer/rust-vobject", branch = "update-errorchain" } +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +vobject = { git = "https://github.com/matthiasbeyer/rust-vobject", branch = "master" } uuid = "0.7" serde = "1" serde_derive = "1" diff --git a/lib/domain/libimagcontact/src/contact.rs b/lib/domain/libimagcontact/src/contact.rs index fb586458..7d8eb644 100644 --- a/lib/domain/libimagcontact/src/contact.rs +++ b/lib/domain/libimagcontact/src/contact.rs @@ -20,15 +20,15 @@ use toml::to_string as toml_to_string; use toml::from_str as toml_from_str; use toml_query::read::TomlValueReadExt; +use failure::Fallible as Result; +use failure::Error; use libimagstore::store::Entry; use libimagentryutil::isa::Is; use libimagentryutil::isa::IsKindHeaderPathProvider; +use libimagerror::errors::ErrorMsg as EM; use deser::DeserVcard; -use error::Result; -use error::ContactError as CE; -use error::ContactErrorKind as CEK; /// Trait to be implemented on ::libimagstore::store::Entry pub trait Contact { @@ -48,14 +48,14 @@ provide_kindflag_path!(pub IsContact, "contact.is_contact"); impl Contact for Entry { fn is_contact(&self) -> Result { - self.is::().map_err(From::from) + self.is::() } fn deser(&self) -> Result { let data = self .get_header() .read("contact.data")? - .ok_or_else(|| CE::from_kind(CEK::HeaderDataMissing("contact.data")))?; + .ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("contact.data")))?; // ugly hack let data_str = toml_to_string(&data)?; diff --git a/lib/domain/libimagcontact/src/error.rs b/lib/domain/libimagcontact/src/error.rs deleted file mode 100644 index 905c5711..00000000 --- a/lib/domain/libimagcontact/src/error.rs +++ /dev/null @@ -1,65 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -use libimagstore::storeid::StoreId; - -error_chain! { - types { - ContactError, ContactErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - VObjectError(::vobject::error::VObjectError, ::vobject::error::VObjectErrorKind); - EntryUtilError(::libimagentryutil::error::EntryUtilError, ::libimagentryutil::error::EntryUtilErrorKind); - } - - foreign_links { - Io(::std::io::Error); - TomlDe(::toml::de::Error); - TomlSer(::toml::ser::Error); - TomlQueryError(::toml_query::error::Error); - UuidError(::uuid::parser::ParseError); - } - - errors { - - HeaderTypeError(ty: &'static str, loc: &'static str) { - description("Type error in header") - display("Type error in header, expected {} at '{}', found other type", ty, loc) - } - - HeaderDataMissing(datapath: &'static str) { - description("Data missing in header") - display("Data missing in header at '{}'", datapath) - } - - EntryNotFound(sid: StoreId) { - description("Entry not found with StoreId") - display("Entry {:?} not found", sid) - } - - UidMissing(buf: String) { - description("Vcard object has no UID") - display("Vcard has no UID : {}", buf) - } - - } -} - diff --git a/lib/domain/libimagcontact/src/iter.rs b/lib/domain/libimagcontact/src/iter.rs index 48f0f403..d175171b 100644 --- a/lib/domain/libimagcontact/src/iter.rs +++ b/lib/domain/libimagcontact/src/iter.rs @@ -20,11 +20,11 @@ use libimagstore::storeid::StoreIdIterator; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; +use libimagerror::errors::ErrorMsg as EM; use contact::Contact; -use error::ContactError as CE; -use error::ContactErrorKind as CEK; -use error::Result; +use failure::Fallible as Result; +use failure::Error; pub struct ContactIter<'a>(StoreIdIterator, &'a Store); @@ -44,11 +44,12 @@ impl<'a> Iterator for ContactIter<'a> { loop { match self.0.next() { None => return None, - Some(Err(e)) => return Some(Err(e).map_err(CE::from)), + Some(Err(e)) => return Some(Err(e).map_err(Error::from)), Some(Ok(sid)) => match self.1.get(sid.clone()).map_err(From::from) { Err(e) => return Some(Err(e)), - Ok(None) => return Some(Err(CE::from_kind(CEK::EntryNotFound(sid)))), - Ok(Some(entry)) => match entry.is_contact().map_err(From::from) { + Ok(None) => return + Some(Err(Error::from(EM::EntryNotFound(sid.local_display_string())))), + Ok(Some(entry)) => match entry.is_contact().map_err(Error::from) { Ok(true) => return Some(Ok(entry)), Ok(false) => continue, Err(e) => return Some(Err(e)), diff --git a/lib/domain/libimagcontact/src/lib.rs b/lib/domain/libimagcontact/src/lib.rs index 87b244e2..7bebea9c 100644 --- a/lib/domain/libimagcontact/src/lib.rs +++ b/lib/domain/libimagcontact/src/lib.rs @@ -36,7 +36,7 @@ #![recursion_limit="128"] #[macro_use] extern crate log; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; extern crate vobject; extern crate toml; extern crate toml_query; @@ -51,7 +51,6 @@ extern crate libimagerror; module_entry_path_mod!("contact"); pub mod contact; -pub mod error; pub mod iter; pub mod store; pub mod deser; diff --git a/lib/domain/libimagcontact/src/store.rs b/lib/domain/libimagcontact/src/store.rs index e2b9aea4..9670454a 100644 --- a/lib/domain/libimagcontact/src/store.rs +++ b/lib/domain/libimagcontact/src/store.rs @@ -24,6 +24,8 @@ use toml::to_string as toml_to_string; use toml::from_str as toml_from_str; use toml_query::insert::TomlValueInsertExt; use vobject::vcard::Vcard; +use failure::Error; +use failure::Fallible as Result; use libimagstore::storeid::IntoStoreId; use libimagstore::storeid::StoreId; @@ -35,9 +37,6 @@ use libimagentryutil::isa::Is; use contact::IsContact; use deser::DeserVcard; use module_path::ModuleEntryPath; -use error::ContactError as CE; -use error::ContactErrorKind as CEK; -use error::Result; use util; pub trait ContactStore<'a> { @@ -95,10 +94,11 @@ impl<'a> ContactStore<'a> for Store { /// /// That means calculating the StoreId and the Value from the vcard data fn prepare_fetching_from_store(buf: &str) -> Result<(StoreId, Value)> { - let vcard = Vcard::build(&buf)?; + let vcard = Vcard::build(&buf).map_err(Error::from)?; debug!("Parsed: {:?}", vcard); - let uid = vcard.uid().ok_or_else(|| CE::from_kind(CEK::UidMissing(buf.to_string())))?; + let uid = vcard.uid() + .ok_or_else(|| Error::from(format_err!("UID Missing: {}", buf.to_string())))?; let value = { // dirty ugly hack let serialized = DeserVcard::from(vcard); diff --git a/lib/domain/libimagcontact/src/util.rs b/lib/domain/libimagcontact/src/util.rs index 53e820c4..e9618574 100644 --- a/lib/domain/libimagcontact/src/util.rs +++ b/lib/domain/libimagcontact/src/util.rs @@ -22,7 +22,7 @@ use std::fmt::Debug; use std::fs::File; use std::io::Read; -use error::Result; +use failure::Fallible as Result; pub fn read_to_string + Debug>(pb: A) -> Result { let mut cont = String::new(); diff --git a/lib/domain/libimagdiary/Cargo.toml b/lib/domain/libimagdiary/Cargo.toml index 218a2233..6b8e1a1a 100644 --- a/lib/domain/libimagdiary/Cargo.toml +++ b/lib/domain/libimagdiary/Cargo.toml @@ -25,7 +25,7 @@ log = "0.4.0" toml = "0.4" toml-query = "0.7" itertools = "0.7" -error-chain = "0.12" +failure = "0.1" filters = "0.3" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } diff --git a/lib/domain/libimagdiary/src/diary.rs b/lib/domain/libimagdiary/src/diary.rs index 779c7d53..32a22ae8 100644 --- a/lib/domain/libimagdiary/src/diary.rs +++ b/lib/domain/libimagdiary/src/diary.rs @@ -29,13 +29,12 @@ use chrono::Datelike; use itertools::Itertools; use chrono::naive::NaiveDateTime; use chrono::Timelike; +use failure::Fallible as Result; +use failure::Error; use entry::IsDiaryEntry; use diaryid::DiaryId; use diaryid::FromStoreId; -use error::DiaryErrorKind as DEK; -use error::ResultExt; -use error::Result; use iter::DiaryEntryIterator; use iter::DiaryNameIterator; @@ -67,7 +66,7 @@ impl Diary for Store { let ndt = dt.naive_local(); let id = DiaryId::new(String::from(diary_name), ndt.year(), ndt.month(), ndt.day(), 0, 0, 0); - let mut entry = self.retrieve(id).chain_err(|| DEK::StoreReadError)?; + let mut entry = self.retrieve(id)?; let _ = entry.set_isflag::()?; Ok(entry) } @@ -87,7 +86,7 @@ impl Diary for Store { ndt.minute(), ndt.second()); - let mut entry = self.retrieve(id).chain_err(|| DEK::StoreReadError)?; + let mut entry = self.retrieve(id)?; let _ = entry.set_isflag::()?; Ok(entry) } @@ -97,15 +96,12 @@ impl Diary for Store { debug!("Building iterator for module 'diary' with diary name = '{}'", diary_name); Store::entries(self) .map(|iter| DiaryEntryIterator::new(String::from(diary_name), iter.without_store())) - .chain_err(|| DEK::StoreReadError) } /// get the id of the youngest entry /// /// TODO: We collect internally here. We shouldn't do that. Solution unclear. fn get_youngest_entry_id(&self, diary_name: &str) -> Option> { - use error::DiaryError as DE; - match Diary::entries(self, diary_name) { Err(e) => Some(Err(e)), Ok(entries) => { @@ -114,7 +110,7 @@ impl Diary for Store { for entry in entries { let entry = match entry { Ok(e) => DiaryId::from_storeid(&e), - Err(e) => return Some(Err(e).map_err(DE::from)), + Err(e) => return Some(Err(e)), }; sorted_entries.push(entry); @@ -156,7 +152,7 @@ impl Diary for Store { fn diary_names(&self) -> Result { self.entries() .map(|it| DiaryNameIterator::new(it.without_store())) - .map_err(::error::DiaryError::from) + .map_err(Error::from) } } diff --git a/lib/domain/libimagdiary/src/diaryid.rs b/lib/domain/libimagdiary/src/diaryid.rs index 70a1270a..3165403c 100644 --- a/lib/domain/libimagdiary/src/diaryid.rs +++ b/lib/domain/libimagdiary/src/diaryid.rs @@ -19,20 +19,20 @@ use std::convert::Into; use std::fmt::{Display, Formatter, Error as FmtError}; +use std::result::Result as RResult; use chrono::naive::NaiveDateTime; use chrono::naive::NaiveTime; use chrono::naive::NaiveDate; use chrono::Datelike; use chrono::Timelike; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; use libimagstore::storeid::StoreId; use libimagstore::storeid::IntoStoreId; -use libimagstore::store::Result as StoreResult; - -use error::DiaryError as DE; -use error::DiaryErrorKind as DEK; -use error::ResultExt; use module_path::ModuleEntryPath; @@ -149,7 +149,7 @@ impl DiaryId { impl IntoStoreId for DiaryId { - fn into_storeid(self) -> StoreResult { + fn into_storeid(self) -> Result { let s : String = self.into(); ModuleEntryPath::new(s).into_storeid() } @@ -167,7 +167,7 @@ impl Into for DiaryId { impl Display for DiaryId { - fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> { write!(fmt, "{}/{:0>4}/{:0>2}/{:0>2}/{:0>2}:{:0>2}:{:0>2}", self.name, self.year, self.month, self.day, self.hour, self.minute, self.second) } @@ -185,32 +185,30 @@ impl Into for DiaryId { } pub trait FromStoreId : Sized { - - fn from_storeid(&StoreId) -> Result; - + fn from_storeid(&StoreId) -> Result; } use std::path::Component; -fn component_to_str<'a>(com: Component<'a>) -> Result<&'a str, DE> { +fn component_to_str<'a>(com: Component<'a>) -> Result<&'a str> { match com { Component::Normal(s) => Some(s), _ => None, }.and_then(|s| s.to_str()) - .ok_or(DE::from_kind(DEK::IdParseError)) + .ok_or_else(|| Error::from(err_msg("ID Parse error"))) } impl FromStoreId for DiaryId { - fn from_storeid(s: &StoreId) -> Result { + fn from_storeid(s: &StoreId) -> Result { use std::str::FromStr; use std::path::Components; use std::iter::Rev; - fn next_component<'a>(components: &'a mut Rev) -> Result<&'a str, DE> { + fn next_component<'a>(components: &'a mut Rev) -> Result<&'a str> { components.next() - .ok_or(DE::from_kind(DEK::IdParseError)) + .ok_or_else(|| Error::from(err_msg("ID parse error"))) .and_then(component_to_str) } @@ -228,21 +226,33 @@ impl FromStoreId for DiaryId { match (hour, minute, second) { (Some(h), Some(m), Some(s)) => Ok((h, m, s)), - _ => return Err(DE::from_kind(DEK::IdParseError)), + _ => return Err(Error::from(err_msg("ID Parse error"))), } })?; - let day: Result = next_component(&mut cmps) - .and_then(|s| s.parse::() - .chain_err(|| DEK::IdParseError)); + let day: Result = next_component(&mut cmps) + .and_then(|s| { + s.parse::() + .map_err(Error::from) + .context(err_msg("ID parse error")) + .map_err(Error::from) + }); - let month: Result = next_component(&mut cmps) - .and_then(|s| s.parse::() - .chain_err(|| DEK::IdParseError)); + let month: Result = next_component(&mut cmps) + .and_then(|s| { + s.parse::() + .map_err(Error::from) + .context(err_msg("ID Parse error")) + .map_err(Error::from) + }); - let year: Result = next_component(&mut cmps) - .and_then(|s| s.parse::() - .chain_err(|| DEK::IdParseError)); + let year: Result = next_component(&mut cmps) + .and_then(|s| { + s.parse::() + .map_err(Error::from) + .context(err_msg("ID Parse error")) + .map_err(Error::from) + }); let name = next_component(&mut cmps).map(String::from); diff --git a/lib/domain/libimagdiary/src/entry.rs b/lib/domain/libimagdiary/src/entry.rs index 82c0b6ba..86e3047c 100644 --- a/lib/domain/libimagdiary/src/entry.rs +++ b/lib/domain/libimagdiary/src/entry.rs @@ -21,9 +21,10 @@ use libimagstore::store::Entry; use libimagentryutil::isa::Is; use libimagentryutil::isa::IsKindHeaderPathProvider; +use failure::Fallible as Result; + use diaryid::DiaryId; use diaryid::FromStoreId; -use error::Result; provide_kindflag_path!(pub IsDiaryEntry, "diary.is_diary_entry"); diff --git a/lib/domain/libimagdiary/src/error.rs b/lib/domain/libimagdiary/src/error.rs deleted file mode 100644 index 8af017b5..00000000 --- a/lib/domain/libimagdiary/src/error.rs +++ /dev/null @@ -1,92 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - DiaryError, DiaryErrorKind, ResultExt, Result; - } - - foreign_links { - Io(::std::io::Error); - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - EntryUtilError(::libimagentryutil::error::EntryUtilError, ::libimagentryutil::error::EntryUtilErrorKind); - } - - errors { - StoreWriteError { - description("Error writing store") - display("Error writing store") - } - - StoreReadError { - description("Error reading store") - display("Error reading store") - } - - CannotFindDiary { - description("Cannot find diary") - display("Cannot find diary") - } - - CannotCreateNote { - description("Cannot create Note object for diary entry") - display("Cannot create Note object for diary entry") - } - - DiaryEditError { - description("Cannot edit diary entry") - display("Cannot edit diary entry") - } - - PathConversionError { - description("Error while converting paths internally") - display("Error while converting paths internally") - } - - EntryNotInDiary { - description("Entry not in Diary") - display("Entry not in Diary") - } - - IOError { - description("IO Error") - display("IO Error") - } - - ViewError { - description("Error viewing diary entry") - display("Error viewing diary entry") - } - - IdParseError { - description("Error while parsing ID") - display("Error while parsing ID") - } - - DiaryNameFindingError { - description("Error while finding a diary name") - display("Error while finding a diary name") - } - - } -} - diff --git a/lib/domain/libimagdiary/src/iter.rs b/lib/domain/libimagdiary/src/iter.rs index 6ebc5230..05e16ef9 100644 --- a/lib/domain/libimagdiary/src/iter.rs +++ b/lib/domain/libimagdiary/src/iter.rs @@ -26,10 +26,9 @@ use libimagstore::storeid::StoreIdIterator; use libimagstore::storeid::StoreId; use is_in_diary::IsInDiary; -use error::DiaryErrorKind as DEK; -use error::DiaryError as DE; -use error::ResultExt; -use error::Result; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; /// A iterator for iterating over diary entries pub struct DiaryEntryIterator { @@ -109,7 +108,7 @@ impl Iterator for DiaryEntryIterator { loop { match self.iter.next() { None => return None, - Some(Err(e)) => return Some(Err(e).map_err(DE::from)), + Some(Err(e)) => return Some(Err(e)), Some(Ok(s)) => { debug!("Next element: {:?}", s); if Filter::filter(self, &s) { @@ -143,16 +142,15 @@ impl Iterator for DiaryNameIterator { fn next(&mut self) -> Option { while let Some(next) = self.0.next() { match next { - Err(e) => return Some(Err(e).map_err(DE::from)), + Err(e) => return Some(Err(e)), Ok(next) => if next.is_in_collection(&["diary"]) { return Some(next .to_str() - .chain_err(|| DEK::DiaryNameFindingError) .and_then(|s| { s.split("diary/") .nth(1) .and_then(|n| n.split("/").nth(0).map(String::from)) - .ok_or(DE::from_kind(DEK::DiaryNameFindingError)) + .ok_or_else(|| Error::from(err_msg("Error finding diary name"))) })); }, } diff --git a/lib/domain/libimagdiary/src/lib.rs b/lib/domain/libimagdiary/src/lib.rs index 416d6e47..ae41c1e3 100644 --- a/lib/domain/libimagdiary/src/lib.rs +++ b/lib/domain/libimagdiary/src/lib.rs @@ -40,7 +40,7 @@ extern crate chrono; extern crate toml; extern crate toml_query; extern crate itertools; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate filters; #[macro_use] extern crate libimagstore; @@ -53,7 +53,6 @@ extern crate libimagrt; module_entry_path_mod!("diary"); pub mod config; -pub mod error; pub mod diaryid; pub mod diary; pub mod is_in_diary; diff --git a/lib/domain/libimagdiary/src/viewer.rs b/lib/domain/libimagdiary/src/viewer.rs index 752f3180..4518b434 100644 --- a/lib/domain/libimagdiary/src/viewer.rs +++ b/lib/domain/libimagdiary/src/viewer.rs @@ -22,11 +22,13 @@ use std::io::Write; use std::ops::Deref; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::err_msg; +use failure::Error; + use libimagstore::store::Entry; use libimagentryview::viewer::Viewer; -use libimagentryview::error::ViewErrorKind as VEK; -use libimagentryview::error::ResultExt; -use libimagentryview::error::Result as ViewResult; use libimagentryview::builtin::plain::PlainViewer; use entry::DiaryEntry; @@ -51,7 +53,7 @@ impl DiaryViewer { impl Viewer for DiaryViewer { - fn view_entry(&self, e: &Entry, sink: &mut W) -> ViewResult<()> + fn view_entry(&self, e: &Entry, sink: &mut W) -> Result<()> where W: Write { self.0.view_entry(e, sink) @@ -59,14 +61,20 @@ impl Viewer for DiaryViewer { /// View all entries from the iterator, or stop immediately if an error occurs, returning that /// error. - fn view_entries(&self, entries: I, sink: &mut W) -> ViewResult<()> + fn view_entries(&self, entries: I, sink: &mut W) -> Result<()> where I: Iterator, E: Deref, W: Write { let mut entries = entries - .map(|e| e.deref().diary_id().map(|id| (id, e)).chain_err(|| VEK::ViewError)) - .collect::>>()?; + .map(|e| { + e.deref() + .diary_id() + .map(|id| (id, e)) + .context(err_msg("View error")) + .map_err(Error::from) + }) + .collect::>>()?; entries.sort_by_key(|&(ref id, _)| { [id.year() as u32, id.month(), id.day(), id.hour(), id.minute(), id.second()] diff --git a/lib/domain/libimaghabit/Cargo.toml b/lib/domain/libimaghabit/Cargo.toml index 5e4eb9b6..451a7a94 100644 --- a/lib/domain/libimaghabit/Cargo.toml +++ b/lib/domain/libimaghabit/Cargo.toml @@ -23,9 +23,9 @@ maintenance = { status = "actively-developed" } chrono = "0.4" log = "0.4" toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" -kairos = { git = "https://github.com/matthiasbeyer/kairos", branch = "master" } +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +kairos = { git = "https://github.com/matthiasbeyer/kairos", branch = "failure" } +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/domain/libimaghabit/src/error.rs b/lib/domain/libimaghabit/src/error.rs deleted file mode 100644 index cc552eb0..00000000 --- a/lib/domain/libimaghabit/src/error.rs +++ /dev/null @@ -1,60 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - HabitError, HabitErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - LinkError(::libimagentrylink::error::LinkError, ::libimagentrylink::error::LinkErrorKind); - KairosError(::kairos::error::KairosError, ::kairos::error::KairosErrorKind); - EntryUtilError(::libimagentryutil::error::EntryUtilError, ::libimagentryutil::error::EntryUtilErrorKind); - } - - foreign_links { - TomlError(::toml_query::error::Error); - ChronoError(::chrono::format::ParseError); - } - - errors { - HabitBuilderMissing(variable_name: &'static str) { - description("Habit builder has not all required information") - display("Habit builder misses {}", variable_name) - } - - HabitBuilderLogicError(text: &'static str) { - description("Logic error in Habit builder") - display("Logic error: {}", text) - } - - HeaderFieldMissing(path: &'static str) { - description("Header field missing") - display("Header field missing: {}", path) - } - - HeaderTypeError(path: &'static str, required_type: &'static str) { - description("Header type error") - display("Header type error: Expected {} at {}, found other type", required_type, path) - } - - } -} - diff --git a/lib/domain/libimaghabit/src/habit.rs b/lib/domain/libimaghabit/src/habit.rs index cd53c290..3c19ac21 100644 --- a/lib/domain/libimaghabit/src/habit.rs +++ b/lib/domain/libimaghabit/src/habit.rs @@ -23,10 +23,10 @@ use toml_query::insert::TomlValueInsertExt; use chrono::NaiveDateTime; use chrono::Local; use chrono::NaiveDate; +use failure::Error; +use failure::Fallible as Result; +use failure::err_msg; -use error::HabitError as HE; -use error::HabitErrorKind as HEK; -use error::*; use iter::HabitInstanceStoreIdIterator; use util::IsHabitCheck; use util::get_string_header_from_entry; @@ -148,7 +148,7 @@ impl HabitTemplate for Entry { match parse(&r)? { Parsed::TimeType(tt) => Ok(tt), Parsed::Iterator(_) => { - Err(format!("'{}' yields an iterator. Cannot use.", r).into()) + Err(format_err!("'{}' yields an iterator. Cannot use.", r)) }, } }; @@ -166,10 +166,7 @@ impl HabitTemplate for Entry { .calculate()? .get_moment() .map(Clone::clone) - .ok_or_else(|| { - let kind : HEK = "until-date seems to have non-date value".to_owned().into(); - HE::from_kind(kind) - }) + .ok_or_else(|| Error::from(err_msg("until-date seems to have non-date value"))) }); debug!("Until-Date is {:?}", basedate); @@ -192,7 +189,7 @@ impl HabitTemplate for Entry { } } } else { - return Err("Iterator seems to return bogus values.".to_owned().into()); + return Err(err_msg("Iterator seems to return bogus values.")); } } @@ -265,7 +262,7 @@ fn instance_id_for_name_and_datestr(habit_name: &String, habit_date: &String) -> ModuleEntryPath::new(format!("instance/{}-{}", habit_name, habit_date)) .into_storeid() - .map_err(HE::from) + .map_err(Error::from) } pub mod builder { @@ -280,9 +277,10 @@ pub mod builder { use libimagentryutil::isa::Is; use libimagutil::debug_result::DebugResult; - use error::HabitError as HE; - use error::HabitErrorKind as HEK; - use error::*; + use failure::Error; + use failure::Fallible as Result; + use failure::err_msg; + use libimagutil::date::date_to_string; use habit::IsHabitTemplate; @@ -324,8 +322,8 @@ pub mod builder { pub fn build<'a>(self, store: &'a Store) -> Result> { #[inline] - fn mkerr(s: &'static str) -> HE { - HE::from_kind(HEK::HabitBuilderMissing(s)) + fn mkerr(s: &'static str) -> Error { + Error::from(format_err!("Habit builder missing: {}", s)) } let name = self.name @@ -336,21 +334,21 @@ pub mod builder { .ok_or_else(|| mkerr("date")) .map_dbg_str("Success: Date present")?; - let recur = self.recurspec + let recur : String = self.recurspec .ok_or_else(|| mkerr("recurspec")) .map_dbg_str("Success: Recurr spec present")?; if let Some(until) = self.untildate { debug!("Success: Until-Date present"); if dateobj > until { - let e = HE::from_kind(HEK::HabitBuilderLogicError("until-date before start date")); + let e = Error::from(err_msg("Habit builder logic error: until-date before start date")); return Err(e); } } - if let Err(e) = ::kairos::parser::parse(&recur) { + if let Err(e) = ::kairos::parser::parse(&recur).map_err(Error::from) { debug!("Kairos failed: {:?}", e); - return Err(e).map_err(From::from); + return Err(e) } let date = date_to_string(&dateobj); debug!("Success: Date valid"); diff --git a/lib/domain/libimaghabit/src/instance.rs b/lib/domain/libimaghabit/src/instance.rs index 3b088bbb..f04c46c9 100644 --- a/lib/domain/libimaghabit/src/instance.rs +++ b/lib/domain/libimaghabit/src/instance.rs @@ -20,8 +20,8 @@ use chrono::NaiveDate; use toml::Value; use toml_query::set::TomlValueSetExt; +use failure::Fallible as Result; -use error::*; use util::*; use libimagstore::store::Entry; diff --git a/lib/domain/libimaghabit/src/iter.rs b/lib/domain/libimaghabit/src/iter.rs index 6a1af765..cdd65e9c 100644 --- a/lib/domain/libimaghabit/src/iter.rs +++ b/lib/domain/libimaghabit/src/iter.rs @@ -17,13 +17,14 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // +use failure::Error; +use failure::Fallible as Result; + use libimagstore::storeid::StoreIdIterator; use libimagstore::storeid::StoreIdIteratorWithStore; use libimagstore::storeid::StoreId; use util::IsHabitCheck; -use error::Result; -use error::HabitError as HE; pub struct HabitTemplateStoreIdIterator(StoreIdIterator); @@ -36,7 +37,7 @@ impl Iterator for HabitTemplateStoreIdIterator { Ok(n) => if n.is_habit_template() { return Some(Ok(n)) }, - Err(e) => return Some(Err(e).map_err(HE::from)), + Err(e) => return Some(Err(e).map_err(Error::from)), } } None @@ -72,7 +73,7 @@ impl Iterator for HabitInstanceStoreIdIterator { Ok(n) => if n.is_habit_instance() { return Some(Ok(n)); }, - Err(e) => return Some(Err(e).map_err(HE::from)), + Err(e) => return Some(Err(e).map_err(Error::from)), } } None diff --git a/lib/domain/libimaghabit/src/lib.rs b/lib/domain/libimaghabit/src/lib.rs index 5272cc6b..c230756f 100644 --- a/lib/domain/libimaghabit/src/lib.rs +++ b/lib/domain/libimaghabit/src/lib.rs @@ -38,7 +38,7 @@ extern crate toml; extern crate toml_query; extern crate kairos; #[macro_use] extern crate log; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; #[macro_use] extern crate libimagstore; extern crate libimagerror; @@ -49,11 +49,9 @@ extern crate libimagutil; module_entry_path_mod!("habit"); -pub mod error; pub mod habit; pub mod instance; pub mod iter; -pub mod result; pub mod store; pub mod util; diff --git a/lib/domain/libimaghabit/src/result.rs b/lib/domain/libimaghabit/src/result.rs deleted file mode 100644 index 904b1de0..00000000 --- a/lib/domain/libimaghabit/src/result.rs +++ /dev/null @@ -1,25 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -use std::result::Result as RResult; - -use error::HabitError; - -pub type Result = RResult; - diff --git a/lib/domain/libimaghabit/src/store.rs b/lib/domain/libimaghabit/src/store.rs index b4f89bfd..489f7413 100644 --- a/lib/domain/libimaghabit/src/store.rs +++ b/lib/domain/libimaghabit/src/store.rs @@ -17,7 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error::Result; +use failure::Fallible as Result; + use habit::builder::HabitBuilder; use iter::HabitTemplateStoreIdIterator; use iter::HabitInstanceStoreIdIterator; diff --git a/lib/domain/libimaghabit/src/util.rs b/lib/domain/libimaghabit/src/util.rs index d9d0e964..bb5b2140 100644 --- a/lib/domain/libimaghabit/src/util.rs +++ b/lib/domain/libimaghabit/src/util.rs @@ -19,13 +19,15 @@ use std::ops::BitXor; -use error::Result; +use failure::Error; +use failure::Fallible as Result; use habit::HabitTemplate; use instance::HabitInstance; use libimagstore::storeid::StoreId; use libimagstore::store::Entry; +use libimagerror::errors::ErrorMsg as EM; /// Helper trait to check whether a object which can be a habit instance and a habit template is /// actually a valid object, whereas "valid" is defined that it is _either_ an instance or a @@ -81,11 +83,11 @@ impl IsHabitCheck for Entry { #[inline] pub fn get_string_header_from_entry(e: &Entry, path: &'static str) -> Result { - use error::HabitErrorKind as HEK; use toml_query::read::TomlValueReadTypeExt; e.get_header() .read_string(path)? - .ok_or(HEK::HeaderFieldMissing(path).into()) + .ok_or_else(|| EM::EntryHeaderFieldMissing(path)) + .map_err(Error::from) } diff --git a/lib/domain/libimaglog/Cargo.toml b/lib/domain/libimaglog/Cargo.toml index 764345f2..08509a93 100644 --- a/lib/domain/libimaglog/Cargo.toml +++ b/lib/domain/libimaglog/Cargo.toml @@ -21,8 +21,8 @@ maintenance = { status = "actively-developed" } [dependencies] toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/domain/libimaglog/src/error.rs b/lib/domain/libimaglog/src/error.rs deleted file mode 100644 index 6b702cb2..00000000 --- a/lib/domain/libimaglog/src/error.rs +++ /dev/null @@ -1,36 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - LogError, LogErrorKind, ResultExt, Result; - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - } - - errors { - HeaderTypeError(expected: &'static str, got: &'static str) { - description("Header Type Error") - display("Error: Expected {} in header, got {}", expected, got) - } - } -} - diff --git a/lib/domain/libimaglog/src/lib.rs b/lib/domain/libimaglog/src/lib.rs index a094bf87..dd35928b 100644 --- a/lib/domain/libimaglog/src/lib.rs +++ b/lib/domain/libimaglog/src/lib.rs @@ -33,14 +33,12 @@ while_true, )] -#[macro_use] -extern crate error_chain; +extern crate failure; extern crate toml; extern crate toml_query; extern crate libimagdiary; extern crate libimagstore; -pub mod error; pub mod log; diff --git a/lib/domain/libimaglog/src/log.rs b/lib/domain/libimaglog/src/log.rs index 30f596d0..e1f22695 100644 --- a/lib/domain/libimaglog/src/log.rs +++ b/lib/domain/libimaglog/src/log.rs @@ -20,8 +20,8 @@ use libimagdiary::entry::DiaryEntry; use libimagstore::store::Entry; -use error::LogError as LE; -use error::Result; +use failure::Fallible as Result; +use failure::Error; use toml::Value; use toml_query::read::TomlValueReadTypeExt; @@ -34,13 +34,13 @@ pub trait Log : DiaryEntry { impl Log for Entry { fn is_log(&self) -> Result { - self.get_header().read_bool("log.is_log").map(|v| v.unwrap_or(false)).map_err(From::from) + self.get_header().read_bool("log.is_log").map(|v| v.unwrap_or(false)).map_err(Error::from) } fn make_log_entry(&mut self) -> Result<()> { self.get_header_mut() .insert("log.is_log", Value::Boolean(true)) - .map_err(LE::from) + .map_err(Error::from) .map(|_| ()) } diff --git a/lib/domain/libimagmail/Cargo.toml b/lib/domain/libimagmail/Cargo.toml index c52f8d7d..05166d93 100644 --- a/lib/domain/libimagmail/Cargo.toml +++ b/lib/domain/libimagmail/Cargo.toml @@ -23,7 +23,7 @@ maintenance = { status = "actively-developed" } log = "0.4.0" email = "0.0.20" filters = "0.3" -error-chain = "0.12" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/domain/libimagmail/src/error.rs b/lib/domain/libimagmail/src/error.rs deleted file mode 100644 index 519eb729..00000000 --- a/lib/domain/libimagmail/src/error.rs +++ /dev/null @@ -1,64 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - MailError, MailErrorKind, ResultExt, Result; - } - - links { - RefError(::libimagentryref::error::RefError, ::libimagentryref::error::RefErrorKind); - } - - foreign_links { - IoError(::std::io::Error); - } - - - errors { - RefCreationError { - description("Error creating a reference to a file/directory") - display("Error creating a reference to a file/directory") - } - - RefHandlingError { - description("Error handling a reference") - display("Error handling a reference") - } - - MailParsingError { - description("Failed to parse mail") - display("Failed to parse mail") - } - - FetchByHashError { - description("Error fetching mail from Store by hash") - display("Error fetching mail from Store by hash") - } - FetchError { - description("Error fetching mail from Store") - display("Error fetching mail from Store") - } - IOError { - description("IO Error") - display("IO Error") - } - } -} - diff --git a/lib/domain/libimagmail/src/iter.rs b/lib/domain/libimagmail/src/iter.rs index 251bc8fb..22fa84bb 100644 --- a/lib/domain/libimagmail/src/iter.rs +++ b/lib/domain/libimagmail/src/iter.rs @@ -25,7 +25,7 @@ //! use mail::Mail; -use error::Result; +use failure::Fallible as Result; use libimagstore::store::FileLockEntry; diff --git a/lib/domain/libimagmail/src/lib.rs b/lib/domain/libimagmail/src/lib.rs index 1439f9b7..fc883404 100644 --- a/lib/domain/libimagmail/src/lib.rs +++ b/lib/domain/libimagmail/src/lib.rs @@ -38,13 +38,12 @@ #[macro_use] extern crate log; extern crate email; extern crate filters; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagerror; extern crate libimagstore; extern crate libimagentryref; -pub mod error; pub mod iter; pub mod mail; diff --git a/lib/domain/libimagmail/src/mail.rs b/lib/domain/libimagmail/src/mail.rs index bf16c4a6..a1b33a14 100644 --- a/lib/domain/libimagmail/src/mail.rs +++ b/lib/domain/libimagmail/src/mail.rs @@ -21,7 +21,6 @@ use std::path::Path; use std::fs::File; use std::io::Read; use std::fs::OpenOptions; -use std::result::Result as RResult; use libimagstore::store::Store; use libimagstore::storeid::StoreId; @@ -29,24 +28,25 @@ use libimagstore::store::FileLockEntry; use libimagentryref::reference::Ref; use libimagentryref::refstore::RefStore; use libimagentryref::refstore::UniqueRefPathGenerator; +use libimagerror::errors::ErrorMsg as EM; use email::MimeMessage; use email::results::ParsingResult as EmailParsingResult; -use error::Result; -use error::{ResultExt, MailError as ME, MailErrorKind as MEK}; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; struct UniqueMailRefGenerator; impl UniqueRefPathGenerator for UniqueMailRefGenerator { - type Error = ME; - /// The collection the `StoreId` should be created for fn collection() -> &'static str { "mail" } /// A function which should generate a unique string for a Path - fn unique_hash>(path: A) -> RResult { + fn unique_hash>(path: A) -> Result { use filters::filter::Filter; use email::Header; @@ -59,7 +59,8 @@ impl UniqueRefPathGenerator for UniqueMailRefGenerator { .read_to_string(&mut s)?; MimeMessage::parse(&s) - .chain_err(|| MEK::RefCreationError) + .context(err_msg("Error creating ref")) + .map_err(Error::from) .and_then(|mail| { let has_key = |hdr: &Header, exp: &str| hdr.name == exp; @@ -73,7 +74,7 @@ impl UniqueRefPathGenerator for UniqueMailRefGenerator { for hdr in mail.headers.iter().filter(|item| filter.filter(item)) { let s = hdr .get_value() - .chain_err(|| MEK::RefCreationError)?; + .context(err_msg("Ref creation error"))?; v.push(s); } @@ -83,7 +84,7 @@ impl UniqueRefPathGenerator for UniqueMailRefGenerator { } /// Postprocess the generated `StoreId` object - fn postprocess_storeid(sid: StoreId) -> RResult { + fn postprocess_storeid(sid: StoreId) -> Result { Ok(sid) } } @@ -113,13 +114,15 @@ impl<'a> Mail<'a> { .and_then(|reference| { debug!("Build reference file: {:?}", reference); reference.get_path() - .chain_err(|| MEK::RefHandlingError) - .and_then(|path| File::open(path).chain_err(|| MEK::IOError)) + .context(err_msg("Ref handling error")) + .map_err(Error::from) + .and_then(|path| File::open(path).context(EM::IO).map_err(Error::from)) .and_then(|mut file| { let mut s = String::new(); file.read_to_string(&mut s) .map(|_| s) - .chain_err(|| MEK::IOError) + .context(EM::IO) + .map_err(Error::from) }) .map(Buffer::from) .map(|buffer| Mail(reference, buffer)) @@ -130,8 +133,9 @@ impl<'a> Mail<'a> { pub fn open>(store: &Store, hash: S) -> Result> { debug!("Opening Mail by Hash"); store.get_ref::(hash) - .chain_err(|| MEK::FetchByHashError) - .chain_err(|| MEK::FetchError) + .context(err_msg("Fetch by hash error")) + .context(err_msg("Fetch error")) + .map_err(Error::from) .and_then(|o| match o { Some(r) => Mail::from_fle(r).map(Some), None => Ok(None), @@ -141,13 +145,15 @@ impl<'a> Mail<'a> { /// Implement me as TryFrom as soon as it is stable pub fn from_fle(fle: FileLockEntry<'a>) -> Result> { fle.get_path() - .chain_err(|| MEK::RefHandlingError) - .and_then(|path| File::open(path).chain_err(|| MEK::IOError)) + .context(err_msg("Ref handling error")) + .map_err(Error::from) + .and_then(|path| File::open(path).context(EM::IO).map_err(Error::from)) .and_then(|mut file| { let mut s = String::new(); file.read_to_string(&mut s) .map(|_| s) - .chain_err(|| MEK::IOError) + .context(EM::IO) + .map_err(Error::from) }) .map(Buffer::from) .map(|buffer| Mail(fle, buffer)) @@ -157,7 +163,8 @@ impl<'a> Mail<'a> { debug!("Getting field in mail: {:?}", field); self.1 .parsed() - .chain_err(|| MEK::MailParsingError) + .context(err_msg("Mail parsing error")) + .map_err(Error::from) .map(|parsed| { parsed.headers .iter() diff --git a/lib/domain/libimagnotes/Cargo.toml b/lib/domain/libimagnotes/Cargo.toml index 64dde6eb..8798250a 100644 --- a/lib/domain/libimagnotes/Cargo.toml +++ b/lib/domain/libimagnotes/Cargo.toml @@ -22,8 +22,8 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/domain/libimagnotes/src/error.rs b/lib/domain/libimagnotes/src/error.rs deleted file mode 100644 index b7b3ae9a..00000000 --- a/lib/domain/libimagnotes/src/error.rs +++ /dev/null @@ -1,46 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - NoteError, NoteErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - } - - errors { - HeaderTypeError { - description("Header type error") - display("Header type error") - } - - NoteToEntryConversion { - description("Error converting Note instance to Entry instance") - display("Error converting Note instance to Entry instance") - } - - } -} - diff --git a/lib/domain/libimagnotes/src/iter.rs b/lib/domain/libimagnotes/src/iter.rs index 98adbbd9..2481da00 100644 --- a/lib/domain/libimagnotes/src/iter.rs +++ b/lib/domain/libimagnotes/src/iter.rs @@ -21,8 +21,8 @@ use libimagstore::storeid::StoreId; use libimagstore::storeid::StoreIdIterator; use notestoreid::*; -use error::Result; -use error::NoteError as NE; +use failure::Fallible as Result; +use failure::Error; #[derive(Debug)] pub struct NoteIterator(StoreIdIterator); @@ -44,7 +44,7 @@ impl Iterator for NoteIterator { Ok(n) => if n.is_note_id() { return Some(Ok(n)); }, - Err(e) => return Some(Err(e).map_err(NE::from)), + Err(e) => return Some(Err(e).map_err(Error::from)), } } diff --git a/lib/domain/libimagnotes/src/lib.rs b/lib/domain/libimagnotes/src/lib.rs index b0ada6fc..c1666519 100644 --- a/lib/domain/libimagnotes/src/lib.rs +++ b/lib/domain/libimagnotes/src/lib.rs @@ -38,7 +38,7 @@ #[macro_use] extern crate log; extern crate toml; extern crate toml_query; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagrt; #[macro_use] extern crate libimagstore; @@ -47,7 +47,6 @@ extern crate libimagentryedit; module_entry_path_mod!("notes"); -pub mod error; pub mod note; pub mod notestore; pub mod notestoreid; diff --git a/lib/domain/libimagnotes/src/note.rs b/lib/domain/libimagnotes/src/note.rs index 001afeff..7da905cc 100644 --- a/lib/domain/libimagnotes/src/note.rs +++ b/lib/domain/libimagnotes/src/note.rs @@ -20,13 +20,13 @@ use toml::Value; use libimagstore::store::Entry; +use libimagerror::errors::ErrorMsg as EM; use toml_query::read::TomlValueReadTypeExt; use toml_query::set::TomlValueSetExt; -use error::Result; -use error::NoteError as NE; -use error::NoteErrorKind as NEK; +use failure::Fallible as Result; +use failure::Error; pub trait Note { fn set_name(&mut self, n: String) -> Result<()>; @@ -40,14 +40,14 @@ impl Note for Entry { fn set_name(&mut self, n: String) -> Result<()> { self.get_header_mut() .set("note.name", Value::String(n)) - .map_err(NE::from) + .map_err(Error::from) .map(|_| ()) } fn get_name(&self) -> Result { self.get_header() .read_string("note.name")? - .ok_or(NE::from_kind(NEK::HeaderTypeError)) + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError)) } fn set_text(&mut self, n: String) { diff --git a/lib/domain/libimagnotes/src/notestore.rs b/lib/domain/libimagnotes/src/notestore.rs index c8331626..9e8acce4 100644 --- a/lib/domain/libimagnotes/src/notestore.rs +++ b/lib/domain/libimagnotes/src/notestore.rs @@ -24,10 +24,9 @@ use libimagstore::store::FileLockEntry; use libimagstore::store::Store; use toml_query::insert::TomlValueInsertExt; +use failure::Fallible as Result; use module_path::ModuleEntryPath; -use error::Result; -use error::NoteError as NE; use iter::*; pub trait NoteStore<'a> { @@ -63,31 +62,19 @@ impl<'a> NoteStore<'a> for Store { } fn delete_note(&'a self, name: String) -> Result<()> { - ModuleEntryPath::new(name) - .into_storeid() - .and_then(|id| self.delete(id)) - .map_err(NE::from) + ModuleEntryPath::new(name).into_storeid().and_then(|id| self.delete(id)) } fn retrieve_note(&'a self, name: String) -> Result> { - ModuleEntryPath::new(name) - .into_storeid() - .and_then(|id| self.retrieve(id)) - .map_err(NE::from) + ModuleEntryPath::new(name).into_storeid().and_then(|id| self.retrieve(id)) } fn get_note(&'a self, name: String) -> Result>> { - ModuleEntryPath::new(name) - .into_storeid() - .and_then(|id| self.get(id)) - .map_err(NE::from) + ModuleEntryPath::new(name).into_storeid().and_then(|id| self.get(id)) } fn all_notes(&'a self) -> Result { - self.entries() - .map(|it| it.without_store()) - .map(NoteIterator::new) - .map_err(NE::from) + self.entries().map(|it| it.without_store()).map(NoteIterator::new) } } diff --git a/lib/domain/libimagtimetrack/Cargo.toml b/lib/domain/libimagtimetrack/Cargo.toml index ed951391..f5837a26 100644 --- a/lib/domain/libimagtimetrack/Cargo.toml +++ b/lib/domain/libimagtimetrack/Cargo.toml @@ -23,10 +23,10 @@ maintenance = { status = "actively-developed" } filters = "0.3" chrono = "0.4" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } lazy_static = "1" is-match = "0.1" -error-chain = "0.12" +failure = "0.1" libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } diff --git a/lib/domain/libimagtimetrack/src/error.rs b/lib/domain/libimagtimetrack/src/error.rs deleted file mode 100644 index d494597e..00000000 --- a/lib/domain/libimagtimetrack/src/error.rs +++ /dev/null @@ -1,53 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - TimeTrackError, TimeTrackErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - DateTimeError(::libimagentrydatetime::error::DateError, ::libimagentrydatetime::error::DateErrorKind); - DatePathError(::libimagentrydatetime::datepath::error::DatePathCompilerError, ::libimagentrydatetime::datepath::error::DatePathCompilerErrorKind); - TomlError(::toml_query::error::Error, ::toml_query::error::ErrorKind); - } - - foreign_links { - ChronoParseError(::chrono::format::ParseError); - } - - errors { - HeaderReadError { - description("Error reading header") - display("Error reading header") - } - - TagFormat { - description("Tag has invalid format") - display("Tag has invalid format") - } - - HeaderFieldTypeError { - description("Type error in header") - display("Type error in header") - } - } -} - diff --git a/lib/domain/libimagtimetrack/src/iter/create.rs b/lib/domain/libimagtimetrack/src/iter/create.rs index d7ffa273..1375d701 100644 --- a/lib/domain/libimagtimetrack/src/iter/create.rs +++ b/lib/domain/libimagtimetrack/src/iter/create.rs @@ -20,9 +20,10 @@ use toml::Value; use toml_query::insert::TomlValueInsertExt; use chrono::naive::NaiveDateTime as NDT; +use failure::Fallible as Result; +use failure::Error; use constants::*; -use error::TimeTrackError as TTE; use iter::storeid::TagStoreIdIter; use iter::setendtime::SetEndTimeIter; @@ -50,7 +51,7 @@ impl<'a> CreateTimeTrackIter<'a> impl<'a> Iterator for CreateTimeTrackIter<'a> { - type Item = Result, TTE>; + type Item = Result>; fn next(&mut self) -> Option { self.inner @@ -59,7 +60,7 @@ impl<'a> Iterator for CreateTimeTrackIter<'a> res.and_then(|(id, starttime)| { self.store .create(id) - .map_err(From::from) + .map_err(Error::from) .and_then(|mut entry| { let v = Value::String(starttime.format(DATE_TIME_FORMAT).to_string()); let _ = entry.get_header_mut().insert(DATE_TIME_START_HEADER_PATH, v)?; diff --git a/lib/domain/libimagtimetrack/src/iter/get.rs b/lib/domain/libimagtimetrack/src/iter/get.rs index 202a87d9..8a4afb28 100644 --- a/lib/domain/libimagtimetrack/src/iter/get.rs +++ b/lib/domain/libimagtimetrack/src/iter/get.rs @@ -19,9 +19,10 @@ use libimagstore::iter::Entries; use libimagstore::store::Store; -use libimagstore::store::Result as StoreResult; use libimagstore::store::FileLockEntry; +use failure::Fallible as Result; + use constants::*; pub struct TimeTrackingsGetIterator<'a>(Entries<'a>, &'a Store); @@ -33,7 +34,7 @@ impl<'a> TimeTrackingsGetIterator<'a> { } impl<'a> Iterator for TimeTrackingsGetIterator<'a> { - type Item = StoreResult>; + type Item = Result>; fn next(&mut self) -> Option { while let Some(next) = self.0.next() { diff --git a/lib/domain/libimagtimetrack/src/iter/setendtime.rs b/lib/domain/libimagtimetrack/src/iter/setendtime.rs index e5706bf3..3d2e4ca1 100644 --- a/lib/domain/libimagtimetrack/src/iter/setendtime.rs +++ b/lib/domain/libimagtimetrack/src/iter/setendtime.rs @@ -20,9 +20,9 @@ use toml::Value; use toml_query::insert::TomlValueInsertExt; use chrono::naive::NaiveDateTime as NDT; +use failure::Fallible as Result; use constants::*; -use error::TimeTrackError as TTE; use iter::create::CreateTimeTrackIter; use libimagstore::store::FileLockEntry; @@ -43,7 +43,7 @@ impl<'a> SetEndTimeIter<'a> } impl<'a> Iterator for SetEndTimeIter<'a> { - type Item = Result, TTE>; + type Item = Result>; fn next(&mut self) -> Option { self.inner diff --git a/lib/domain/libimagtimetrack/src/iter/storeid.rs b/lib/domain/libimagtimetrack/src/iter/storeid.rs index 2932663b..91656a3f 100644 --- a/lib/domain/libimagtimetrack/src/iter/storeid.rs +++ b/lib/domain/libimagtimetrack/src/iter/storeid.rs @@ -18,9 +18,10 @@ // use chrono::naive::NaiveDateTime as NDT; +use failure::Fallible as Result; +use failure::Error; use constants::*; -use error::TimeTrackError; use iter::tag::TagIter; use iter::create::CreateTimeTrackIter; @@ -48,7 +49,7 @@ impl TagStoreIdIter { } impl Iterator for TagStoreIdIter { - type Item = Result<(StoreId, NDT), TimeTrackError>; + type Item = Result<(StoreId, NDT)>; fn next(&mut self) -> Option { use module_path::ModuleEntryPath; @@ -62,7 +63,7 @@ impl Iterator for TagStoreIdIter { let id_str = format!("{}-{}", dt, tag.as_str()); ModuleEntryPath::new(id_str) .into_storeid() - .map_err(From::from) + .map_err(Error::from) .map(|id| (id, self.datetime.clone())) }) }) diff --git a/lib/domain/libimagtimetrack/src/iter/tag.rs b/lib/domain/libimagtimetrack/src/iter/tag.rs index e8589445..3d479a25 100644 --- a/lib/domain/libimagtimetrack/src/iter/tag.rs +++ b/lib/domain/libimagtimetrack/src/iter/tag.rs @@ -18,10 +18,10 @@ // use chrono::naive::NaiveDateTime as NDT; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; -use error::TimeTrackError; -use error::TimeTrackErrorKind as TTEK; -use error::TimeTrackError as TTE; use tag::TimeTrackingTag as TTT; use iter::storeid::TagStoreIdIter; @@ -40,7 +40,7 @@ impl TagIter { } impl Iterator for TagIter { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { self.0 @@ -48,7 +48,7 @@ impl Iterator for TagIter { .map(|t| if is_tag_str(&t).is_ok() { Ok(TTT::from(t)) } else { - Err(TTE::from_kind(TTEK::TagFormat)) + Err(Error::from(err_msg("Error in Tag format"))) }) } } diff --git a/lib/domain/libimagtimetrack/src/lib.rs b/lib/domain/libimagtimetrack/src/lib.rs index 952ac918..37fbbc7b 100644 --- a/lib/domain/libimagtimetrack/src/lib.rs +++ b/lib/domain/libimagtimetrack/src/lib.rs @@ -43,7 +43,7 @@ extern crate toml_query; extern crate lazy_static; #[macro_use] extern crate is_match; -#[macro_use] extern crate error_chain; +extern crate failure; #[macro_use] extern crate libimagstore; @@ -52,7 +52,6 @@ extern crate libimagentrytag; extern crate libimagerror; mod constants; -pub mod error; pub mod timetracking; pub mod timetrackingstore; pub mod iter; diff --git a/lib/domain/libimagtimetrack/src/tag.rs b/lib/domain/libimagtimetrack/src/tag.rs index dfaf9a48..9ee40c68 100644 --- a/lib/domain/libimagtimetrack/src/tag.rs +++ b/lib/domain/libimagtimetrack/src/tag.rs @@ -21,8 +21,10 @@ use std::fmt::Display; use std::fmt::Error as FmtError; use std::fmt::Formatter; use std::path::PathBuf; +use std::result::Result as RResult; + +use failure::Fallible as Result; -use libimagstore::store::Result as StoreResult; use libimagstore::storeid::IntoStoreId; use libimagstore::storeid::StoreId; @@ -38,7 +40,7 @@ impl TimeTrackingTag { } impl Display for TimeTrackingTag { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + fn fmt(&self, f: &mut Formatter) -> RResult<(), FmtError> { self.0.fmt(f) } } @@ -62,7 +64,7 @@ impl<'a> From<&'a String> for TimeTrackingTag { } impl IntoStoreId for TimeTrackingTag { - fn into_storeid(self) -> StoreResult { + fn into_storeid(self) -> Result { StoreId::new_baseless(PathBuf::from(self.0)) } } diff --git a/lib/domain/libimagtimetrack/src/timetracking.rs b/lib/domain/libimagtimetrack/src/timetracking.rs index 51e3384c..e39e5c9c 100644 --- a/lib/domain/libimagtimetrack/src/timetracking.rs +++ b/lib/domain/libimagtimetrack/src/timetracking.rs @@ -27,17 +27,17 @@ use chrono::naive::NaiveDateTime; use libimagstore::store::Entry; +use libimagerror::errors::ErrorMsg as EM; use tag::TimeTrackingTag as TTT; -use error::TimeTrackErrorKind as TTEK; -use error::TimeTrackError as TTE; -use error::Result; use constants::*; use toml::Value; use toml_query::delete::TomlValueDeleteExt; use toml_query::insert::TomlValueInsertExt; use toml_query::read::TomlValueReadTypeExt; +use failure::Fallible as Result; +use failure::Error; pub trait TimeTracking { @@ -64,8 +64,8 @@ impl TimeTracking for Entry { fn get_timetrack_tag(&self) -> Result { self.get_header() .read_string(DATE_TIME_TAG_HEADER_PATH) - .map_err(TTE::from)? - .ok_or(TTE::from_kind(TTEK::HeaderReadError)) + .map_err(Error::from)? + .ok_or_else(|| Error::from(EM::EntryHeaderReadError)) .map(Into::into) } @@ -74,21 +74,21 @@ impl TimeTracking for Entry { self.get_header_mut() .insert(DATE_TIME_START_HEADER_PATH, Value::String(s)) - .map_err(From::from) + .map_err(Error::from) .map(|_| ()) } fn get_start_datetime(&self) -> Result> { self.get_header() .read_string(DATE_TIME_START_HEADER_PATH) - .map_err(From::from) + .map_err(Error::from) .and_then(header_value_to_dt) } fn delete_start_datetime(&mut self) -> Result<()> { self.get_header_mut() .delete(DATE_TIME_START_HEADER_PATH) - .map_err(From::from) + .map_err(Error::from) .map(|_| ()) } @@ -97,21 +97,21 @@ impl TimeTracking for Entry { self.get_header_mut() .insert(DATE_TIME_END_HEADER_PATH, Value::String(s)) - .map_err(From::from) + .map_err(Error::from) .map(|_| ()) } fn get_end_datetime(&self) -> Result> { self.get_header() .read_string(DATE_TIME_END_HEADER_PATH) - .map_err(From::from) + .map_err(Error::from) .and_then(header_value_to_dt) } fn delete_end_datetime(&mut self) -> Result<()> { self.get_header_mut() .delete(DATE_TIME_END_HEADER_PATH) - .map_err(From::from) + .map_err(Error::from) .map(|_| ()) } @@ -135,7 +135,7 @@ impl TimeTracking for Entry { fn header_value_to_dt(val: Option) -> Result> { match val { - Some(ref s) => NaiveDateTime::parse_from_str(s, DATE_TIME_FORMAT).map_err(TTE::from).map(Some), + Some(ref s) => NaiveDateTime::parse_from_str(s, DATE_TIME_FORMAT).map_err(Error::from).map(Some), None => Ok(None), } } diff --git a/lib/domain/libimagtimetrack/src/timetrackingstore.rs b/lib/domain/libimagtimetrack/src/timetrackingstore.rs index 72e608ae..1d8b27cd 100644 --- a/lib/domain/libimagtimetrack/src/timetrackingstore.rs +++ b/lib/domain/libimagtimetrack/src/timetrackingstore.rs @@ -25,12 +25,13 @@ use chrono::NaiveDateTime as NDT; use toml::Value; use toml_query::insert::TomlValueInsertExt; +use failure::Fallible as Result; +use failure::Error; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; use libimagentrydatetime::datepath::compiler::DatePathCompiler; -use error::Result; use constants::*; use iter::get::TimeTrackingsGetIterator; @@ -69,24 +70,24 @@ impl<'a> TimeTrackStore<'a> for Store { use std::path::PathBuf; COMPILER.compile(CRATE_NAME, start) - .map_err(From::from) + .map_err(Error::from) .map(|mut id| { id.local_push(PathBuf::from(ts.as_str())); id }) - .and_then(|id| self.create(id).map_err(From::from)) + .and_then(|id| self.create(id)) .and_then(|mut fle| { let v = Value::String(ts.as_str().to_owned()); fle.get_header_mut() .insert(DATE_TIME_TAG_HEADER_PATH, v) - .map_err(From::from) + .map_err(Error::from) .map(|_| fle) }) .and_then(|mut fle| { let v = Value::String(start.format(DATE_TIME_FORMAT).to_string()); fle.get_header_mut() .insert(DATE_TIME_START_HEADER_PATH, v) - .map_err(From::from) + .map_err(Error::from) .map(|_| fle) }) } @@ -97,7 +98,7 @@ impl<'a> TimeTrackStore<'a> for Store { let v = Value::String(end.format(DATE_TIME_FORMAT).to_string()); fle.get_header_mut() .insert(DATE_TIME_END_HEADER_PATH, v) - .map_err(From::from) + .map_err(Error::from) .map(|_| fle) }) } diff --git a/lib/domain/libimagtodo/Cargo.toml b/lib/domain/libimagtodo/Cargo.toml index 696f5978..a7f88e46 100644 --- a/lib/domain/libimagtodo/Cargo.toml +++ b/lib/domain/libimagtodo/Cargo.toml @@ -20,13 +20,13 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } maintenance = { status = "actively-developed" } [dependencies] -task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs", branch = "master" } +task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs", branch = "failure" } uuid = "0.7" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } log = "0.4.0" serde_json = "1" -error-chain = "0.12" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/domain/libimagtodo/src/error.rs b/lib/domain/libimagtodo/src/error.rs deleted file mode 100644 index 7498d387..00000000 --- a/lib/domain/libimagtodo/src/error.rs +++ /dev/null @@ -1,70 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - TodoError, TodoErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - } - - errors { - ConversionError { - description("Conversion Error") - display("Conversion Error") - } - - StoreIdError { - description("Store Id handling error") - display("Store Id handling error") - } - - ImportError { - description("Error importing") - display("Error importing") - } - - UTF8Error { - description("Encountered non-UTF8 characters while reading input") - display("Encountered non-UTF8 characters while reading input") - } - - HeaderFieldMissing { - description("Header field missing") - display("Header field missing") - } - - HeaderTypeError { - description("Header field type error") - display("Header field type error") - } - - UuidParserError { - description("Uuid parser error") - display("Uuid parser error") - } - } -} - diff --git a/lib/domain/libimagtodo/src/iter.rs b/lib/domain/libimagtodo/src/iter.rs index c5c63943..1d7b7494 100644 --- a/lib/domain/libimagtodo/src/iter.rs +++ b/lib/domain/libimagtodo/src/iter.rs @@ -20,8 +20,7 @@ use libimagstore::storeid::StoreIdIterator; use libimagstore::storeid::StoreId; -use error::Result; -use error::TodoError as TE; +use failure::Fallible as Result; pub struct TaskIdIterator(StoreIdIterator); @@ -40,7 +39,7 @@ impl Iterator for TaskIdIterator { loop { match self.0.next() { None => return None, - Some(Err(e)) => return Some(Err(e).map_err(TE::from)), + Some(Err(e)) => return Some(Err(e)), Some(Ok(n)) => if n.is_in_collection(&["todo", "taskwarrior"]) { return Some(Ok(n)) }, // else continue diff --git a/lib/domain/libimagtodo/src/lib.rs b/lib/domain/libimagtodo/src/lib.rs index 09927b79..b28b2831 100644 --- a/lib/domain/libimagtodo/src/lib.rs +++ b/lib/domain/libimagtodo/src/lib.rs @@ -40,7 +40,7 @@ extern crate toml; extern crate toml_query; #[macro_use] extern crate log; extern crate serde_json; -#[macro_use] extern crate error_chain; +extern crate failure; #[macro_use] extern crate libimagstore; extern crate libimagerror; @@ -48,7 +48,6 @@ extern crate task_hookrs; module_entry_path_mod!("todo"); -pub mod error; pub mod task; pub mod taskstore; pub mod iter; diff --git a/lib/domain/libimagtodo/src/task.rs b/lib/domain/libimagtodo/src/task.rs index b16cec06..9df96e27 100644 --- a/lib/domain/libimagtodo/src/task.rs +++ b/lib/domain/libimagtodo/src/task.rs @@ -17,12 +17,13 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error::TodoError as TE; -use error::TodoErrorKind as TEK; -use error::ResultExt; -use error::Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; +use failure::Fallible as Result; use libimagstore::store::Entry; +use libimagerror::errors::ErrorMsg as EM; use uuid::Uuid; use toml_query::read::TomlValueReadTypeExt; @@ -35,8 +36,10 @@ impl Task for Entry { fn get_uuid(&self) -> Result { self.get_header() .read_string("todo.uuid")? - .ok_or(TE::from_kind(TEK::HeaderFieldMissing)) - .and_then(|u| Uuid::parse_str(&u).chain_err(|| TEK::UuidParserError)) + .ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("todo.uuid"))) + .and_then(|u| { + Uuid::parse_str(&u).context(err_msg("UUID Parser error")).map_err(Error::from) + }) } } diff --git a/lib/domain/libimagtodo/src/taskstore.rs b/lib/domain/libimagtodo/src/taskstore.rs index a85696e4..a66f9516 100644 --- a/lib/domain/libimagtodo/src/taskstore.rs +++ b/lib/domain/libimagtodo/src/taskstore.rs @@ -26,15 +26,16 @@ use uuid::Uuid; use task_hookrs::task::Task as TTask; use task_hookrs::import::{import_task, import_tasks}; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; use libimagstore::store::{FileLockEntry, Store}; use libimagstore::storeid::IntoStoreId; +use libimagerror::errors::ErrorMsg as EM; use module_path::ModuleEntryPath; -use error::TodoErrorKind as TEK; -use error::TodoError as TE; -use error::Result; -use error::ResultExt; use iter::TaskIdIterator; /// Task struct containing a `FileLockEntry` @@ -55,9 +56,10 @@ impl<'a> TaskStore<'a> for Store { fn import_task_from_reader(&'a self, mut r: R) -> Result<(FileLockEntry<'a>, String, Uuid)> { let mut line = String::new(); - r.read_line(&mut line).map_err(|_| TE::from_kind(TEK::UTF8Error))?; + r.read_line(&mut line).context(EM::UTF8Error)?; import_task(&line.as_str()) - .map_err(|_| TE::from_kind(TEK::ImportError)) + .context(err_msg("Error importing")) + .map_err(Error::from) .and_then(|t| { let uuid = t.uuid().clone(); self.new_from_twtask(t).map(|t| (t, line, uuid)) @@ -75,7 +77,7 @@ impl<'a> TaskStore<'a> for Store { /// fn get_task_from_import(&'a self, mut r: R) -> Result, String>> { let mut line = String::new(); - r.read_line(&mut line).chain_err(|| TEK::UTF8Error)?; + r.read_line(&mut line).context(EM::UTF8Error)?; self.get_task_from_string(line) } @@ -85,7 +87,8 @@ impl<'a> TaskStore<'a> for Store { /// For an explanation on the return values see `Task::get_from_import()`. fn get_task_from_string(&'a self, s: String) -> Result, String>> { import_task(s.as_str()) - .map_err(|_| TE::from_kind(TEK::ImportError)) + .context(err_msg("Import error")) + .map_err(Error::from) .map(|t| t.uuid().clone()) .and_then(|uuid| self.get_task_from_uuid(uuid)) .and_then(|o| match o { @@ -101,14 +104,13 @@ impl<'a> TaskStore<'a> for Store { ModuleEntryPath::new(format!("taskwarrior/{}", uuid)) .into_storeid() .and_then(|store_id| self.get(store_id)) - .map_err(TE::from) } /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to /// implicitely create the task if it does not exist. fn retrieve_task_from_import(&'a self, mut r: R) -> Result> { let mut line = String::new(); - r.read_line(&mut line).chain_err(|| TEK::UTF8Error)?; + r.read_line(&mut line).context(EM::UTF8Error)?; self.retrieve_task_from_string(line) } @@ -119,7 +121,8 @@ impl<'a> TaskStore<'a> for Store { .and_then(|opt| match opt { Ok(task) => Ok(task), Err(string) => import_task(string.as_str()) - .map_err(|_| TE::from_kind(TEK::ImportError)) + .context(err_msg("Import error")) + .map_err(Error::from) .and_then(|t| self.new_from_twtask(t)), }) } @@ -129,33 +132,25 @@ impl<'a> TaskStore<'a> for Store { use task_hookrs::status::TaskStatus; for (counter, res_ttask) in import_tasks(r).into_iter().enumerate() { - match res_ttask { - Ok(ttask) => { - if counter % 2 == 1 { - // Only every second task is needed, the first one is the - // task before the change, and the second one after - // the change. The (maybe modified) second one is - // expected by taskwarrior. - match serde_to_string(&ttask).chain_err(|| TEK::ImportError) { - // use println!() here, as we talk with TW - Ok(val) => println!("{}", val), - Err(e) => return Err(e), - } + let ttask = res_ttask.context(err_msg("Import error"))?; - // Taskwarrior does not have the concept of deleted tasks, but only modified - // ones. - // - // Here we check if the status of a task is deleted and if yes, we delete it - // from the store. - if *ttask.status() == TaskStatus::Deleted { - match self.delete_task_by_uuid(*ttask.uuid()) { - Ok(_) => info!("Deleted task {}", *ttask.uuid()), - Err(e) => return Err(e), - } - } - } // end if c % 2 - }, - Err(_) => return Err(TE::from_kind(TEK::ImportError)), + if counter % 2 == 1 { + // Only every second task is needed, the first one is the + // task before the change, and the second one after + // the change. The (maybe modified) second one is + // expected by taskwarrior. + let val = serde_to_string(&ttask).context(err_msg("Import error"))?; + println!("{}", val); + + // Taskwarrior does not have the concept of deleted tasks, but only modified + // ones. + // + // Here we check if the status of a task is deleted and if yes, we delete it + // from the store. + if *ttask.status() == TaskStatus::Deleted { + let _ = self.delete_task_by_uuid(*ttask.uuid())?; + info!("Deleted task {}", *ttask.uuid()); + } } } Ok(()) @@ -165,13 +160,10 @@ impl<'a> TaskStore<'a> for Store { ModuleEntryPath::new(format!("taskwarrior/{}", uuid)) .into_storeid() .and_then(|id| self.delete(id)) - .map_err(TE::from) } fn all_tasks(&self) -> Result { - self.entries() - .map(|i| TaskIdIterator::new(i.without_store())) - .map_err(TE::from) + self.entries().map(|i| TaskIdIterator::new(i.without_store())) } fn new_from_twtask(&'a self, task: TTask) -> Result> { @@ -181,10 +173,8 @@ impl<'a> TaskStore<'a> for Store { let uuid = task.uuid(); ModuleEntryPath::new(format!("taskwarrior/{}", uuid)) .into_storeid() - .chain_err(|| TEK::StoreIdError) .and_then(|id| { self.retrieve(id) - .map_err(TE::from) .and_then(|mut fle| { { let hdr = fle.get_header_mut(); diff --git a/lib/domain/libimagwiki/Cargo.toml b/lib/domain/libimagwiki/Cargo.toml index cd693876..c5671793 100644 --- a/lib/domain/libimagwiki/Cargo.toml +++ b/lib/domain/libimagwiki/Cargo.toml @@ -21,10 +21,10 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4" -error-chain = "0.12" toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } filters = "0.3" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/domain/libimagwiki/src/entry.rs b/lib/domain/libimagwiki/src/entry.rs index 39b9d805..6d1972fa 100644 --- a/lib/domain/libimagwiki/src/entry.rs +++ b/lib/domain/libimagwiki/src/entry.rs @@ -21,9 +21,9 @@ use libimagstore::store::Store; use libimagstore::store::Entry; use libimagentrymarkdown::processor::LinkProcessor; -use error::Result; -use error::WikiErrorKind as WEK; -use error::ResultExt; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; pub trait WikiEntry { fn autolink(&mut self, store: &Store) -> Result<()>; @@ -67,7 +67,9 @@ impl WikiEntry for Entry { /// /// See the documentation of `::libimagentrymarkdown::processor::LinkProcessor`. fn autolink_with_processor(&mut self, store: &Store, processor: LinkProcessor) -> Result<()> { - processor.process(self, store).chain_err(|| WEK::AutoLinkError(self.get_location().clone())) + processor.process(self, store) + .context(format_err!("Auto Link error: {}", self.get_location())) + .map_err(Error::from) } } diff --git a/lib/domain/libimagwiki/src/error.rs b/lib/domain/libimagwiki/src/error.rs deleted file mode 100644 index 185f71f8..00000000 --- a/lib/domain/libimagwiki/src/error.rs +++ /dev/null @@ -1,55 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -use libimagstore::storeid::StoreId; - -error_chain! { - types { - WikiError, WikiErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - LinkError(::libimagentrylink::error::LinkError, ::libimagentrylink::error::LinkErrorKind); - } - - errors { - WikiDoesNotExist(name: String) { - description("Wiki does not exist") - display("Wiki '{}' does not exist", name) - } - - WikiExists(name: String) { - description("Wiki exist already") - display("Wiki '{}' exists already", name) - } - - AutoLinkError(sid: StoreId) { - description("Error while autolinking entry") - display("Error while autolinking entry: {}", sid) - } - - MissingIndex { - description("Index page for wiki is missing") - display("Index page for wiki is missing") - } - } - -} - diff --git a/lib/domain/libimagwiki/src/lib.rs b/lib/domain/libimagwiki/src/lib.rs index ef1801c1..abfa9f4c 100644 --- a/lib/domain/libimagwiki/src/lib.rs +++ b/lib/domain/libimagwiki/src/lib.rs @@ -39,7 +39,7 @@ extern crate filters; extern crate toml; extern crate toml_query; #[macro_use] extern crate log; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; #[macro_use] extern crate libimagstore; extern crate libimagerror; @@ -49,7 +49,6 @@ extern crate libimagentrymarkdown; module_entry_path_mod!("wiki"); pub mod entry; -pub mod error; pub mod store; pub mod wiki; diff --git a/lib/domain/libimagwiki/src/store.rs b/lib/domain/libimagwiki/src/store.rs index 7113aa17..89b7093b 100644 --- a/lib/domain/libimagwiki/src/store.rs +++ b/lib/domain/libimagwiki/src/store.rs @@ -21,8 +21,8 @@ use libimagstore::store::Store; use libimagstore::storeid::StoreId; use libimagstore::storeid::IntoStoreId; -use error::WikiError as WE; -use error::Result; +use failure::Fallible as Result; + use wiki::Wiki; pub trait WikiStore { @@ -79,6 +79,6 @@ impl WikiStore for Store { } fn wiki_path(name: &str) -> Result { - ::module_path::ModuleEntryPath::new(name).into_storeid().map_err(WE::from) + ::module_path::ModuleEntryPath::new(name).into_storeid() } diff --git a/lib/domain/libimagwiki/src/wiki.rs b/lib/domain/libimagwiki/src/wiki.rs index da194fd4..c3888710 100644 --- a/lib/domain/libimagwiki/src/wiki.rs +++ b/lib/domain/libimagwiki/src/wiki.rs @@ -29,9 +29,8 @@ use libimagstore::storeid::StoreId; use libimagstore::storeid::StoreIdIteratorWithStore; use libimagentrylink::internal::InternalLinker; -use error::WikiError as WE; -use error::WikiErrorKind as WEK; -use error::Result; +use failure::Fallible as Result; +use failure::err_msg; pub struct Wiki<'a, 'b>(&'a Store, &'b str); @@ -54,15 +53,13 @@ impl<'a, 'b> Wiki<'a, 'b> { let path = PathBuf::from(format!("{}/index", self.1)); let sid = ::module_path::ModuleEntryPath::new(path).into_storeid()?; - self.0 - .create(sid) - .map_err(WE::from) + self.0.create(sid) } pub fn get_entry>(&self, entry_name: EN) -> Result>> { let path = PathBuf::from(format!("{}/{}", self.1, entry_name.as_ref())); let sid = ::module_path::ModuleEntryPath::new(path).into_storeid()?; - self.0.get(sid).map_err(WE::from) + self.0.get(sid) } pub fn create_entry>(&self, entry_name: EN) -> Result> { @@ -70,13 +67,10 @@ impl<'a, 'b> Wiki<'a, 'b> { let sid = ::module_path::ModuleEntryPath::new(path).into_storeid()?; let mut index = self .get_entry("index")? - .ok_or_else(|| WEK::MissingIndex.into()) - .map_err(WE::from_kind)?; + .ok_or_else(|| err_msg("Missing index page"))?; let mut entry = self.0.create(sid)?; - entry.add_internal_link(&mut index) - .map_err(WE::from) - .map(|_| entry) + entry.add_internal_link(&mut index).map(|_| entry) } pub fn retrieve_entry>(&self, entry_name: EN) -> Result> { @@ -84,13 +78,10 @@ impl<'a, 'b> Wiki<'a, 'b> { let sid = ::module_path::ModuleEntryPath::new(path).into_storeid()?; let mut index = self .get_entry("index")? - .ok_or_else(|| WEK::MissingIndex.into()) - .map_err(WE::from_kind)?; + .ok_or_else(|| err_msg("Missing index page"))?; let mut entry = self.0.retrieve(sid)?; - entry.add_internal_link(&mut index) - .map_err(WE::from) - .map(|_| entry) + entry.add_internal_link(&mut index).map(|_| entry) } pub fn all_ids(&self) -> Result { @@ -101,7 +92,7 @@ impl<'a, 'b> Wiki<'a, 'b> { pub fn delete_entry>(&self, entry_name: EN) -> Result<()> { let path = PathBuf::from(format!("{}/{}", self.1, entry_name.as_ref())); let sid = ::module_path::ModuleEntryPath::new(path).into_storeid()?; - self.0.delete(sid).map_err(WE::from) + self.0.delete(sid) } } @@ -116,7 +107,7 @@ impl<'a> Iterator for WikiIdIterator<'a> { Ok(next) => if self.1.filter(&next) { return Some(Ok(next)); }, - Err(e) => return Some(Err(e).map_err(WE::from)), + Err(e) => return Some(Err(e)), } } diff --git a/lib/entry/libimagentryannotation/Cargo.toml b/lib/entry/libimagentryannotation/Cargo.toml index 085beed4..506a1213 100644 --- a/lib/entry/libimagentryannotation/Cargo.toml +++ b/lib/entry/libimagentryannotation/Cargo.toml @@ -22,8 +22,9 @@ maintenance = { status = "actively-developed" } [dependencies] lazy_static = "1" toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" +failure_derive = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/entry/libimagentryannotation/src/annotateable.rs b/lib/entry/libimagentryannotation/src/annotateable.rs index d38b9c66..c9c6f2d6 100644 --- a/lib/entry/libimagentryannotation/src/annotateable.rs +++ b/lib/entry/libimagentryannotation/src/annotateable.rs @@ -31,9 +31,10 @@ use libimagentryutil::isa::IsKindHeaderPathProvider; use toml_query::read::TomlValueReadTypeExt; use toml_query::insert::TomlValueInsertExt; -use error::Result; -use error::AnnotationErrorKind as AEK; -use error::ResultExt; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; use iter::*; @@ -52,7 +53,6 @@ impl Annotateable for Entry { fn annotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result> { use module_path::ModuleEntryPath; store.retrieve(ModuleEntryPath::new(ann_name).into_storeid()?) - .map_err(From::from) .and_then(|mut anno| { { let _ = anno.set_isflag::()?; @@ -64,7 +64,8 @@ impl Annotateable for Entry { }) .and_then(|mut anno| { anno.add_internal_link(self) - .chain_err(|| AEK::LinkingError) + .context(err_msg("Linking error")) + .map_err(Error::from) .map(|_| anno) }) } @@ -91,13 +92,12 @@ impl Annotateable for Entry { /// Get all annotations of an entry fn annotations<'a>(&self, store: &'a Store) -> Result> { self.get_internal_links() - .map_err(From::from) .map(|iter| StoreIdIterator::new(Box::new(iter.map(|e| e.get_store_id().clone()).map(Ok)))) .map(|i| AnnotationIter::new(i, store)) } fn is_annotation(&self) -> Result { - self.is::().map_err(From::from) + self.is::() } } diff --git a/lib/entry/libimagentryannotation/src/annotation_fetcher.rs b/lib/entry/libimagentryannotation/src/annotation_fetcher.rs index ef98bdfd..854f5038 100644 --- a/lib/entry/libimagentryannotation/src/annotation_fetcher.rs +++ b/lib/entry/libimagentryannotation/src/annotation_fetcher.rs @@ -19,7 +19,7 @@ use libimagstore::store::Store; -use error::Result; +use failure::Fallible as Result; use iter::*; pub trait AnnotationFetcher<'a> { diff --git a/lib/entry/libimagentryannotation/src/error.rs b/lib/entry/libimagentryannotation/src/error.rs deleted file mode 100644 index 1a6c644d..00000000 --- a/lib/entry/libimagentryannotation/src/error.rs +++ /dev/null @@ -1,68 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - AnnotationError, AnnotationErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - LinkError(::libimagentrylink::error::LinkError, ::libimagentrylink::error::LinkErrorKind); - EntryUtilError(::libimagentryutil::error::EntryUtilError, ::libimagentryutil::error::EntryUtilErrorKind); - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - } - - errors { - StoreReadError { - description("Store read error") - display("Store read error") - } - - StoreWriteError { - description("Store write error") - display("Store write error") - } - - LinkingError { - description("Error while linking") - display("Error while linking") - } - - HeaderWriteError { - description("Couldn't write Header for annotation") - display("Couldn't write Header for annotation") - } - - HeaderReadError { - description("Couldn't read Header of Entry") - display("Couldn't read Header of Entry") - } - - HeaderTypeError { - description("Header field has unexpected type") - display("Header field has unexpected type") - } - - } -} - diff --git a/lib/entry/libimagentryannotation/src/iter.rs b/lib/entry/libimagentryannotation/src/iter.rs index 9485ba07..977ff0f9 100644 --- a/lib/entry/libimagentryannotation/src/iter.rs +++ b/lib/entry/libimagentryannotation/src/iter.rs @@ -22,11 +22,12 @@ use toml_query::read::TomlValueReadTypeExt; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreIdIterator; +use libimagerror::errors::ErrorMsg as EM; -use error::Result; -use error::AnnotationError as AE; -use error::AnnotationErrorKind as AEK; -use error::ResultExt; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; #[derive(Debug)] pub struct AnnotationIter<'a>(StoreIdIterator, &'a Store); @@ -46,11 +47,20 @@ impl<'a> Iterator for AnnotationIter<'a> { loop { match self.0.next() { None => return None, // iterator consumed - Some(Err(e)) => return Some(Err(e).map_err(AE::from)), + Some(Err(e)) => return Some(Err(e).map_err(Error::from)), Some(Ok(id)) => match self.1.get(id) { - Err(e) => return Some(Err(e).chain_err(|| AEK::StoreReadError)), + Err(e) => { + return Some(Err(e) + .context(err_msg("Store read error")) + .map_err(Error::from)) + }, Ok(Some(entry)) => { - match entry.get_header().read_bool("annotation.is_annotation").chain_err(|| AEK::HeaderReadError) { + match entry + .get_header() + .read_bool("annotation.is_annotation") + .context(EM::EntryHeaderReadError) + .map_err(Error::from) + { Ok(None) => continue, // not an annotation Ok(Some(false)) => continue, Ok(Some(true)) => return Some(Ok(entry)), diff --git a/lib/entry/libimagentryannotation/src/lib.rs b/lib/entry/libimagentryannotation/src/lib.rs index 8c83eae7..cb904135 100644 --- a/lib/entry/libimagentryannotation/src/lib.rs +++ b/lib/entry/libimagentryannotation/src/lib.rs @@ -37,7 +37,7 @@ extern crate toml; extern crate toml_query; -#[macro_use] extern crate error_chain; +extern crate failure; #[macro_use] extern crate libimagstore; extern crate libimagerror; @@ -48,6 +48,5 @@ module_entry_path_mod!("annotations"); pub mod annotateable; pub mod annotation_fetcher; -pub mod error; pub mod iter; diff --git a/lib/entry/libimagentrycategory/Cargo.toml b/lib/entry/libimagentrycategory/Cargo.toml index 174b699f..29107a7a 100644 --- a/lib/entry/libimagentrycategory/Cargo.toml +++ b/lib/entry/libimagentrycategory/Cargo.toml @@ -20,10 +20,10 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } maintenance = { status = "actively-developed" } [dependencies] -log = "0.4.0" -toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" +log = "0.4.0" +toml = "0.4" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } diff --git a/lib/entry/libimagentrycategory/src/category.rs b/lib/entry/libimagentrycategory/src/category.rs index 8da3342f..ac40e63b 100644 --- a/lib/entry/libimagentrycategory/src/category.rs +++ b/lib/entry/libimagentrycategory/src/category.rs @@ -26,9 +26,9 @@ use libimagentrylink::internal::InternalLinker; use toml_query::read::TomlValueReadTypeExt; -use error::Result; -use error::CategoryError as CE; -use error::CategoryErrorKind as CEK; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; use store::CATEGORY_REGISTER_NAME_FIELD_PATH; use iter::CategoryEntryIterator; @@ -42,15 +42,15 @@ pub trait Category { impl Category for Entry { fn is_category(&self) -> Result { - self.is::().map_err(CE::from) + self.is::() } fn get_name(&self) -> Result { trace!("Getting category name of '{:?}'", self.get_location()); self.get_header() .read_string(CATEGORY_REGISTER_NAME_FIELD_PATH) - .map_err(CE::from)? - .ok_or_else(|| CE::from_kind(CEK::CategoryNameMissing)) + .map_err(Error::from)? + .ok_or_else(|| Error::from(err_msg("Category name missing"))) } fn get_entries<'a>(&self, store: &'a Store) -> Result> { diff --git a/lib/entry/libimagentrycategory/src/entry.rs b/lib/entry/libimagentrycategory/src/entry.rs index 624b5fa1..5b798ac4 100644 --- a/lib/entry/libimagentrycategory/src/entry.rs +++ b/lib/entry/libimagentrycategory/src/entry.rs @@ -24,11 +24,12 @@ use toml::Value; use libimagstore::store::Entry; use libimagentrylink::internal::InternalLinker; +use libimagerror::errors::ErrorMsg as EM; -use error::CategoryErrorKind as CEK; -use error::CategoryError as CE; -use error::ResultExt; -use error::Result; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; use store::CategoryStore; pub trait EntryCategory { @@ -51,7 +52,9 @@ impl EntryCategory for Entry { trace!("Setting category '{}' UNCHECKED", s); self.get_header_mut() .insert(&String::from("category.value"), Value::String(s.to_string())) - .chain_err(|| CEK::HeaderWriteError) + .map_err(Error::from) + .context(EM::EntryHeaderWriteError) + .map_err(Error::from) .map(|_| ()) } @@ -62,7 +65,7 @@ impl EntryCategory for Entry { trace!("Setting category '{}' checked", s); let mut category = register .get_category_by_name(s)? - .ok_or_else(|| CE::from_kind(CEK::CategoryDoesNotExist))?; + .ok_or_else(|| Error::from(err_msg("Category does not exist")))?; let _ = self.set_category(s)?; let _ = self.add_internal_link(&mut category)?; @@ -74,13 +77,16 @@ impl EntryCategory for Entry { trace!("Getting category from '{}'", self.get_location()); self.get_header() .read_string("category.value")? - .ok_or_else(|| CE::from_kind(CEK::CategoryNameMissing)) + .ok_or_else(|| Error::from(err_msg("Category name missing"))) } fn has_category(&self) -> Result { trace!("Has category? '{}'", self.get_location()); - self.get_header().read("category.value") - .chain_err(|| CEK::HeaderReadError) + self.get_header() + .read("category.value") + .map_err(Error::from) + .context(EM::EntryHeaderReadError) + .map_err(Error::from) .map(|x| x.is_some()) } @@ -95,9 +101,10 @@ impl EntryCategory for Entry { self.get_header_mut() .delete("category.value") - .chain_err(|| CEK::HeaderWriteError) + .map_err(Error::from) + .context(EM::EntryHeaderWriteError) + .map_err(Error::from) .map(|_| ()) } - } diff --git a/lib/entry/libimagentrycategory/src/error.rs b/lib/entry/libimagentrycategory/src/error.rs deleted file mode 100644 index f9b90ff3..00000000 --- a/lib/entry/libimagentrycategory/src/error.rs +++ /dev/null @@ -1,77 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - CategoryError, CategoryErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - LinkError(::libimagentrylink::error::LinkError, ::libimagentrylink::error::LinkErrorKind); - EntryUtilError(::libimagentryutil::error::EntryUtilError, ::libimagentryutil::error::EntryUtilErrorKind); - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - } - - errors { - StoreReadError { - description("Store Read error") - display("Store Read error") - } - - StoreWriteError { - description("Store Write error") - display("Store Write error") - } - - StoreIdHandlingError { - description("StoreId handling error") - display("StoreId handling error") - } - - HeaderReadError { - description("Header read error") - display("Header read error") - } - - HeaderWriteError { - description("Header write error") - display("Header write error") - } - - CategoryDoesNotExist { - description("Category does not exist") - display("Category does not exist") - } - - TypeError { - description("Type Error") - display("Type Error") - } - - CategoryNameMissing { - description("Category name is missing") - display("Category name is missing") - } - } -} - diff --git a/lib/entry/libimagentrycategory/src/iter.rs b/lib/entry/libimagentrycategory/src/iter.rs index ac143025..e525eabf 100644 --- a/lib/entry/libimagentrycategory/src/iter.rs +++ b/lib/entry/libimagentrycategory/src/iter.rs @@ -20,15 +20,16 @@ use libimagstore::storeid::StoreIdIterator; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; +use libimagerror::errors::ErrorMsg as EM; use toml_query::read::TomlValueReadTypeExt; -use error::Result; -use error::CategoryError as CE; -use error::CategoryErrorKind as CEK; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; use store::CATEGORY_REGISTER_NAME_FIELD_PATH; use entry::EntryCategory; -use error::ResultExt; /// Iterator for Category names /// @@ -61,17 +62,18 @@ impl<'a> Iterator for CategoryNameIter<'a> { while let Some(sid) = self.1.next() { match sid { - Err(e) => return Some(Err(e).map_err(CE::from)), + Err(e) => return Some(Err(e).map_err(Error::from)), Ok(sid) => { if sid.is_in_collection(&["category"]) { let func = |store: &Store| { // hack for returning Some(Result<_, _>) store .get(sid)? - .ok_or_else(|| CE::from_kind(CEK::StoreReadError))? + .ok_or_else(|| Error::from(err_msg("Store read error")))? .get_header() .read_string(query) - .chain_err(|| CEK::HeaderReadError)? - .ok_or_else(|| CE::from_kind(CEK::StoreReadError)) + .map_err(Error::from) + .context(EM::EntryHeaderReadError)? + .ok_or_else(|| Error::from(err_msg("Store read error"))) }; return Some(func(&self.0)) @@ -98,12 +100,12 @@ impl<'a> Iterator for CategoryEntryIterator<'a> { fn next(&mut self) -> Option { while let Some(next) = self.1.next() { match next { - Err(e) => return Some(Err(e).map_err(CE::from)), + Err(e) => return Some(Err(e).map_err(Error::from)), Ok(next) => { let getter = |next| -> Result<(String, FileLockEntry<'a>)> { let entry = self.0 .get(next)? - .ok_or_else(|| CE::from_kind(CEK::StoreReadError))?; + .ok_or_else(|| Error::from(err_msg("Store read error")))?; Ok((entry.get_category()?, entry)) }; diff --git a/lib/entry/libimagentrycategory/src/lib.rs b/lib/entry/libimagentrycategory/src/lib.rs index 0f0e1189..28b1cf59 100644 --- a/lib/entry/libimagentrycategory/src/lib.rs +++ b/lib/entry/libimagentrycategory/src/lib.rs @@ -39,7 +39,7 @@ extern crate toml_query; extern crate toml; #[macro_use] extern crate log; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagerror; #[macro_use] extern crate libimagstore; @@ -49,7 +49,6 @@ extern crate libimagentrylink; pub mod category; pub mod entry; -pub mod error; pub mod store; pub mod iter; diff --git a/lib/entry/libimagentrycategory/src/store.rs b/lib/entry/libimagentrycategory/src/store.rs index 1058c7bb..7a569fa7 100644 --- a/lib/entry/libimagentrycategory/src/store.rs +++ b/lib/entry/libimagentrycategory/src/store.rs @@ -27,11 +27,12 @@ use libimagstore::store::Store; use libimagstore::store::FileLockEntry; use libimagstore::storeid::StoreId; use libimagentryutil::isa::Is; +use libimagerror::errors::ErrorMsg as EM; -use error::CategoryErrorKind as CEK; -use error::CategoryError as CE; -use error::ResultExt; -use error::Result; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; use iter::CategoryNameIter; use category::IsCategory; @@ -93,8 +94,8 @@ impl CategoryStore for Store { { let mut category = self.get(sid.clone())? - .ok_or_else(|| CEK::CategoryDoesNotExist) - .map_err(CE::from_kind)?; + .ok_or_else(|| Error::from(err_msg("Category does not exist"))) + .map_err(Error::from)?; for entry in category.get_entries(self)? { let mut entry = entry?; @@ -102,7 +103,7 @@ impl CategoryStore for Store { } } - self.delete(sid).map_err(CE::from) + self.delete(sid) } /// Get all category names @@ -120,7 +121,8 @@ impl CategoryStore for Store { let sid = mk_category_storeid(self.path().clone(), name)?; self.get(sid) - .chain_err(|| CEK::StoreWriteError) + .context(err_msg("Store write error")) + .map_err(Error::from) } } @@ -215,23 +217,26 @@ fn mk_category_storeid(base: PathBuf, s: &str) -> Result { ::module_path::ModuleEntryPath::new(s) .into_storeid() .map(|id| id.with_base(base)) - .chain_err(|| CEK::StoreIdHandlingError) + .context(err_msg("Store id handling error")) + .map_err(Error::from) } #[inline] fn represents_category(store: &Store, sid: StoreId, name: &str) -> Result { sid.exists() - .chain_err(|| CEK::StoreIdHandlingError) + .context(err_msg("Store id handling error")) + .map_err(Error::from) .and_then(|bl| { if bl { store.get(sid) - .chain_err(|| CEK::StoreReadError) + .context(err_msg("Store read error")) + .map_err(Error::from) .and_then(|fle| { if let Some(fle) = fle { fle.get_header() .read_string(&String::from(CATEGORY_REGISTER_NAME_FIELD_PATH)) - .chain_err(|| CEK::HeaderReadError)? - .ok_or(CE::from_kind(CEK::TypeError)) + .context(EM::EntryHeaderReadError)? + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError)) .map(|s| s == name) } else { Ok(false) diff --git a/lib/entry/libimagentrydatetime/Cargo.toml b/lib/entry/libimagentrydatetime/Cargo.toml index 26d7e69e..3844d8da 100644 --- a/lib/entry/libimagentrydatetime/Cargo.toml +++ b/lib/entry/libimagentrydatetime/Cargo.toml @@ -21,10 +21,10 @@ maintenance = { status = "actively-developed" } [dependencies] chrono = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } lazy_static = "1" toml = "0.4" -error-chain = "0.12" +failure = "0.1" libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } diff --git a/lib/entry/libimagentrydatetime/src/datepath/compiler.rs b/lib/entry/libimagentrydatetime/src/datepath/compiler.rs index b9ef0c66..71a0c3ad 100644 --- a/lib/entry/libimagentrydatetime/src/datepath/compiler.rs +++ b/lib/entry/libimagentrydatetime/src/datepath/compiler.rs @@ -27,9 +27,7 @@ use libimagstore::storeid::StoreId; use datepath::accuracy::Accuracy; use datepath::format::Format; -use datepath::error::Result; -use datepath::error::DatePathCompilerErrorKind as DPCEK; -use datepath::error::ResultExt; +use failure::Fallible as Result; pub struct DatePathCompiler { accuracy : Accuracy, @@ -122,7 +120,6 @@ impl DatePathCompiler { } StoreId::new_baseless(PathBuf::from(s)) - .chain_err(|| DPCEK::StoreIdBuildFailed) } } diff --git a/lib/entry/libimagentrydatetime/src/datepath/error.rs b/lib/entry/libimagentrydatetime/src/datepath/error.rs deleted file mode 100644 index f6a5cef3..00000000 --- a/lib/entry/libimagentrydatetime/src/datepath/error.rs +++ /dev/null @@ -1,38 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - DatePathCompilerError, DatePathCompilerErrorKind, ResultExt, Result; - } - - errors { - UnknownDatePathCompilerError { - description("Unknown DatePathCompiler error") - display("Unknown DatePathCompiler error") - } - - StoreIdBuildFailed { - description("Failed building StoreId object") - display("Failed building StoreId object") - } - - } -} - diff --git a/lib/entry/libimagentrydatetime/src/datepath/mod.rs b/lib/entry/libimagentrydatetime/src/datepath/mod.rs index 9aef1dcc..27e5c515 100644 --- a/lib/entry/libimagentrydatetime/src/datepath/mod.rs +++ b/lib/entry/libimagentrydatetime/src/datepath/mod.rs @@ -19,7 +19,6 @@ pub mod accuracy; pub mod compiler; -pub mod error; pub mod format; pub mod to_store_id; diff --git a/lib/entry/libimagentrydatetime/src/datepath/to_store_id.rs b/lib/entry/libimagentrydatetime/src/datepath/to_store_id.rs index baf302ca..1cb59de7 100644 --- a/lib/entry/libimagentrydatetime/src/datepath/to_store_id.rs +++ b/lib/entry/libimagentrydatetime/src/datepath/to_store_id.rs @@ -18,9 +18,9 @@ // use chrono::naive::NaiveDateTime; +use failure::Fallible as Result; use libimagstore::storeid::StoreId; -use datepath::error::Result; use datepath::compiler::DatePathCompiler; // diff --git a/lib/entry/libimagentrydatetime/src/datetime.rs b/lib/entry/libimagentrydatetime/src/datetime.rs index 790f9f84..f4e671cc 100644 --- a/lib/entry/libimagentrydatetime/src/datetime.rs +++ b/lib/entry/libimagentrydatetime/src/datetime.rs @@ -24,10 +24,12 @@ use toml_query::read::TomlValueReadTypeExt; use toml::Value; use libimagstore::store::Entry; +use libimagerror::errors::ErrorMsg as EM; -use error::DateErrorKind as DEK; -use error::DateError as DE; -use error::*; +use failure::Error; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::err_msg; use range::DateTimeRange; pub trait EntryDate { @@ -55,16 +57,18 @@ impl EntryDate for Entry { self.get_header_mut() .delete(&DATE_HEADER_LOCATION) .map(|_| ()) - .chain_err(|| DEK::DeleteDateError) + .context("Delete date error") + .map_err(Error::from) } fn read_date(&self) -> Result { self.get_header() .read_string(&DATE_HEADER_LOCATION) - .chain_err(|| DEK::ReadDateError)? - .ok_or(DE::from_kind(DEK::ReadDateError))? + .context("Error while reading date")? + .ok_or_else(|| err_msg("Error reading date"))? .parse::() - .chain_err(|| DEK::DateTimeParsingError) + .context("Datetime parse error") + .map_err(Error::from) } /// Set a Date for this entry @@ -88,13 +92,16 @@ impl EntryDate for Entry { self.get_header_mut() .insert(&DATE_HEADER_LOCATION, Value::String(date)) + .map_err(Error::from) .map(|opt| opt.map(|stri| { stri.as_str() - .ok_or(DE::from_kind(DEK::DateHeaderFieldTypeError))? + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError))? .parse::() - .chain_err(|| DEK::DateTimeParsingError) + .context("Datetime parse error") + .map_err(Error::from) })) - .chain_err(|| DEK::SetDateError) + .context("Error setting date") + .map_err(Error::from) } @@ -110,30 +117,33 @@ impl EntryDate for Entry { .get_header_mut() .delete(&DATE_RANGE_START_HEADER_LOCATION) .map(|_| ()) - .chain_err(|| DEK::DeleteDateTimeRangeError)?; + .context("Delete Datetime range error")?; self.get_header_mut() .delete(&DATE_RANGE_END_HEADER_LOCATION) .map(|_| ()) - .chain_err(|| DEK::DeleteDateTimeRangeError) + .context("Delete Datetime range error") + .map_err(Error::from) } fn read_date_range(&self) -> Result { let start = self .get_header() .read_string(&DATE_RANGE_START_HEADER_LOCATION) - .chain_err(|| DEK::ReadDateTimeRangeError)? - .ok_or_else(|| DE::from_kind(DEK::ReadDateError)) + .context("Error while reading Datetime range")? + .ok_or_else(|| err_msg("Error reading date")) .and_then(str_to_ndt)?; let end = self .get_header() .read_string(&DATE_RANGE_START_HEADER_LOCATION) - .chain_err(|| DEK::ReadDateTimeRangeError)? - .ok_or_else(|| DE::from_kind(DEK::ReadDateError)) + .context("Error reading Datetime range")? + .ok_or_else(|| err_msg("Error reading date")) .and_then(str_to_ndt)?; - DateTimeRange::new(start, end).chain_err(|| DEK::DateTimeRangeError) + DateTimeRange::new(start, end) + .context("Datetime Range error") + .map_err(Error::from) } /// Set the date range @@ -153,18 +163,19 @@ impl EntryDate for Entry { .get_header_mut() .insert(&DATE_RANGE_START_HEADER_LOCATION, Value::String(start)) .map(|opt| opt.as_ref().map(val_to_ndt)) - .chain_err(|| DEK::SetDateTimeRangeError)?; + .context("Error setting Datetime range")?; let opt_old_end = self .get_header_mut() .insert(&DATE_RANGE_END_HEADER_LOCATION, Value::String(end)) .map(|opt| opt.as_ref().map(val_to_ndt)) - .chain_err(|| DEK::SetDateTimeRangeError)?; + .context("Error setting Datetime range")?; match (opt_old_start, opt_old_end) { (Some(Ok(old_start)), Some(Ok(old_end))) => { let dr = DateTimeRange::new(old_start, old_end) - .chain_err(|| DEK::DateTimeRangeError); + .context("Error processing Datetime range") + .map_err(Error::from); Ok(Some(dr)) }, @@ -181,15 +192,18 @@ impl EntryDate for Entry { #[inline] fn str_to_ndt(v: String) -> Result { - v.parse::().chain_err(|| DEK::DateTimeParsingError) + v.parse::() + .context("Error parsing Datetime") + .map_err(Error::from) } #[inline] fn val_to_ndt(v: &Value) -> Result { v.as_str() - .ok_or(DE::from_kind(DEK::DateHeaderFieldTypeError))? + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError))? .parse::() - .chain_err(|| DEK::DateTimeParsingError) + .context("Datetime parsing error") + .map_err(Error::from) } #[cfg(test)] diff --git a/lib/entry/libimagentrydatetime/src/error.rs b/lib/entry/libimagentrydatetime/src/error.rs deleted file mode 100644 index 70b90c82..00000000 --- a/lib/entry/libimagentrydatetime/src/error.rs +++ /dev/null @@ -1,77 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - DateError, DateErrorKind, ResultExt, Result; - } - - errors { - DeleteDateError { - description("Error deleting date") - display("Error deleting date") - } - - ReadDateError { - description("Error reading date") - display("Error reading date") - } - - SetDateError { - description("Error setting date") - display("Error setting date") - } - - DeleteDateTimeRangeError { - description("Error deleting date-time range") - display("Error deleting date-time range") - } - - ReadDateTimeRangeError { - description("Error reading date-time range") - display("Error reading date-time range") - } - - SetDateTimeRangeError { - description("Error setting date-time range") - display("Error setting date-time range") - } - - DateTimeRangeError { - description("DateTime Range error") - display("DateTime Range error") - } - - DateHeaderFieldTypeError { - description("Expected the header field in the entry to have type 'String', but have other type") - display("Expected the header field in the entry to have type 'String', but have other type") - } - - DateTimeParsingError { - description("Error parsing DateTime") - display("Error parsing DateTime") - } - - EndDateTimeBeforeStartDateTime { - description("End datetime is before start datetime") - display("End datetime is before start datetime") - } - } -} - diff --git a/lib/entry/libimagentrydatetime/src/lib.rs b/lib/entry/libimagentrydatetime/src/lib.rs index 03655d32..37f59035 100644 --- a/lib/entry/libimagentrydatetime/src/lib.rs +++ b/lib/entry/libimagentrydatetime/src/lib.rs @@ -39,13 +39,12 @@ extern crate chrono; extern crate toml_query; extern crate toml; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagerror; extern crate libimagstore; pub mod datepath; pub mod datetime; -pub mod error; pub mod range; diff --git a/lib/entry/libimagentrydatetime/src/range.rs b/lib/entry/libimagentrydatetime/src/range.rs index 0cb4b484..b3580e68 100644 --- a/lib/entry/libimagentrydatetime/src/range.rs +++ b/lib/entry/libimagentrydatetime/src/range.rs @@ -19,9 +19,8 @@ use chrono::naive::NaiveDateTime; -use error::DateErrorKind as DEK; -use error::DateError as DE; -use error::Result; +use failure::Fallible as Result; +use failure::err_msg; /// A Range between two dates #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -40,7 +39,7 @@ impl DateTimeRange { if start < end { Ok(DateTimeRange(start, end)) } else { - Err(DE::from_kind(DEK::EndDateTimeBeforeStartDateTime)) + Err(err_msg("End date before start date")) } } diff --git a/lib/entry/libimagentryedit/Cargo.toml b/lib/entry/libimagentryedit/Cargo.toml index 7ca095ad..726518e5 100644 --- a/lib/entry/libimagentryedit/Cargo.toml +++ b/lib/entry/libimagentryedit/Cargo.toml @@ -22,6 +22,7 @@ maintenance = { status = "actively-developed" } [dependencies] error-chain = "0.12" toml = "0.4" +failure = "0.1" libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } diff --git a/lib/entry/libimagentryedit/src/edit.rs b/lib/entry/libimagentryedit/src/edit.rs index 33af2c2b..021f0814 100644 --- a/lib/entry/libimagentryedit/src/edit.rs +++ b/lib/entry/libimagentryedit/src/edit.rs @@ -20,10 +20,12 @@ use libimagrt::runtime::Runtime; use libimagstore::store::Entry; -use error::Result; -use error::EditErrorKind; -use error::EditError as EE; -use error::ResultExt; +use failure::Fallible as Result; +use failure::Error; +use failure::ResultExt; +use failure::err_msg; + +use libimagerror::errors::ErrorMsg as EM; pub trait Edit { fn edit_content(&mut self, rt: &Runtime) -> Result<()>; @@ -64,7 +66,7 @@ impl EditHeader for Entry { fn edit_header_and_content(&mut self, rt: &Runtime) -> Result<()> { let mut header_and_content = self.to_str()?; let _ = edit_in_tmpfile(rt, &mut header_and_content)?; - self.replace_from_buffer(&header_and_content).map_err(EE::from) + self.replace_from_buffer(&header_and_content).map_err(Error::from) } } @@ -74,17 +76,16 @@ pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> { let editor = rt .editor() - .chain_err(|| EditErrorKind::NoEditor)? - .ok_or_else(|| EE::from_kind(EditErrorKind::NoEditor))?; + .context(err_msg("No editor"))? + .ok_or_else(|| Error::from(err_msg("No editor")))?; edit_in_tmpfile_with_command(editor, s) - .chain_err(|| EditErrorKind::IOError) - .and_then(|worked| { - if !worked { - Err(EditErrorKind::ProcessExitFailure.into()) - } else { - Ok(()) - } + .context(EM::IO) + .map_err(Error::from) + .and_then(|worked| if !worked { + Err(Error::from(EM::ExternalProcessError)) + } else { + Ok(()) }) } diff --git a/lib/entry/libimagentryedit/src/error.rs b/lib/entry/libimagentryedit/src/error.rs deleted file mode 100644 index 039dd0c5..00000000 --- a/lib/entry/libimagentryedit/src/error.rs +++ /dev/null @@ -1,58 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - EditError, EditErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - } - - foreign_links { - TomlSerError(::toml::ser::Error); - TomlDeserError(::toml::de::Error); - } - - - errors { - IOError { - description("IO Error") - display("IO Error") - } - - NoEditor { - description("No editor set") - display("No editor set") - } - - ProcessExitFailure { - description("Process did not exit properly") - display("Process did not exit properly") - } - - InstantiateError { - description("Instantation error") - display("Instantation error") - } - - } -} - diff --git a/lib/entry/libimagentryedit/src/lib.rs b/lib/entry/libimagentryedit/src/lib.rs index 29a09073..6de64153 100644 --- a/lib/entry/libimagentryedit/src/lib.rs +++ b/lib/entry/libimagentryedit/src/lib.rs @@ -39,8 +39,7 @@ extern crate libimagerror; extern crate libimagstore; extern crate libimagrt; extern crate libimagutil; -#[macro_use] extern crate error_chain; extern crate toml; +extern crate failure; pub mod edit; -pub mod error; diff --git a/lib/entry/libimagentryfilter/Cargo.toml b/lib/entry/libimagentryfilter/Cargo.toml index 573ea576..cd017512 100644 --- a/lib/entry/libimagentryfilter/Cargo.toml +++ b/lib/entry/libimagentryfilter/Cargo.toml @@ -26,10 +26,12 @@ log = "0.4.0" regex = "1" semver = "0.9" toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" +failure_derive = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } +libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } libimagentrytag = { version = "0.9.0", path = "../../../lib/entry/libimagentrytag" } [dependencies.clap] diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_eq.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_eq.rs index 9562dddd..d6d1393c 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_eq.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_eq.rs @@ -23,8 +23,9 @@ use builtin::header::field_path::FieldPath; use builtin::header::field_predicate::FieldPredicate; use builtin::header::field_predicate::Predicate; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; use toml::Value; @@ -56,7 +57,7 @@ impl FieldEq { } impl FailableFilter for FieldEq { - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { self.filter.filter(e) diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_exists.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_exists.rs index 76428874..0032135b 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_exists.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_exists.rs @@ -21,8 +21,9 @@ use libimagstore::store::Entry; use toml_query::read::TomlValueReadExt; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; use builtin::header::field_path::FieldPath; @@ -41,10 +42,13 @@ impl FieldExists { } impl FailableFilter for FieldExists { - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { - e.get_header().read(&self.header_field_path[..]).map_err(FE::from).map(|o| o.is_some()) + e.get_header() + .read(&self.header_field_path[..]) + .map_err(Error::from) + .map(|o| o.is_some()) } } diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_grep.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_grep.rs index 5367eee8..6734bac5 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_grep.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_grep.rs @@ -26,8 +26,9 @@ use builtin::header::field_path::FieldPath; use builtin::header::field_predicate::FieldPredicate; use builtin::header::field_predicate::Predicate; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; struct EqGrep{ regex: Regex @@ -60,7 +61,7 @@ impl FieldGrep { } impl FailableFilter for FieldGrep { - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { self.filter.filter(e) diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_gt.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_gt.rs index b7e629bc..4cbaa74f 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_gt.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_gt.rs @@ -23,8 +23,9 @@ use builtin::header::field_path::FieldPath; use builtin::header::field_predicate::FieldPredicate; use builtin::header::field_predicate::Predicate; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; use toml::Value; @@ -72,7 +73,7 @@ impl FieldGt { } impl FailableFilter for FieldGt { - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { self.filter.filter(e) diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs index d1c4721e..afb4dfe5 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs @@ -22,8 +22,9 @@ use toml_query::read::TomlValueReadExt; use builtin::header::field_path::FieldPath; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; use toml::Value; @@ -42,7 +43,7 @@ impl FieldIsEmpty { } impl FailableFilter for FieldIsEmpty { - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { Ok(e diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_istype.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_istype.rs index a0968d37..2d840517 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_istype.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_istype.rs @@ -23,8 +23,9 @@ use builtin::header::field_path::FieldPath; use builtin::header::field_predicate::FieldPredicate; use builtin::header::field_predicate::Predicate; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; use toml::Value; @@ -81,7 +82,7 @@ impl FieldIsType { } impl FailableFilter for FieldIsType { - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { self.filter.filter(e) diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_lt.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_lt.rs index c9b89fec..0db1aa07 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_lt.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_lt.rs @@ -23,8 +23,9 @@ use builtin::header::field_path::FieldPath; use builtin::header::field_predicate::FieldPredicate; use builtin::header::field_predicate::Predicate; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; use toml::Value; @@ -72,7 +73,7 @@ impl FieldLt { } impl FailableFilter for FieldLt { - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { self.filter.filter(e) diff --git a/lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs b/lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs index 5a7dbb9b..520ec5c1 100644 --- a/lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs +++ b/lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs @@ -24,8 +24,9 @@ use toml::Value; use builtin::header::field_path::FieldPath; use filters::failable::filter::FailableFilter; -use error::Result; -use error::FilterError as FE; + +use failure::Fallible as Result; +use failure::Error; pub trait Predicate { fn evaluate(&self, &Value) -> bool; @@ -53,7 +54,7 @@ impl FieldPredicate

{ } impl FailableFilter for FieldPredicate

{ - type Error = FE; + type Error = Error; fn filter(&self, e: &Entry) -> Result { Ok(e.get_header() diff --git a/lib/entry/libimagentryfilter/src/error.rs b/lib/entry/libimagentryfilter/src/error.rs deleted file mode 100644 index 370b3fb9..00000000 --- a/lib/entry/libimagentryfilter/src/error.rs +++ /dev/null @@ -1,34 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - - types { - FilterError, FilterErrorKind, ResultExt, Result; - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - } - - errors { - } - -} - diff --git a/lib/entry/libimagentryfilter/src/lib.rs b/lib/entry/libimagentryfilter/src/lib.rs index b7870fe1..2a58f2af 100644 --- a/lib/entry/libimagentryfilter/src/lib.rs +++ b/lib/entry/libimagentryfilter/src/lib.rs @@ -38,16 +38,16 @@ extern crate regex; extern crate semver; extern crate toml; extern crate toml_query; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagstore; extern crate libimagentrytag; +extern crate libimagerror; // core functionality modules of the crate, // these depend only on libimagstore pub mod builtin; -pub mod error; // extended functionality of the crate // these depend on other internal libraries than libimagstore and use the upper core modules for diff --git a/lib/entry/libimagentrygps/Cargo.toml b/lib/entry/libimagentrygps/Cargo.toml index 9c224824..cc166259 100644 --- a/lib/entry/libimagentrygps/Cargo.toml +++ b/lib/entry/libimagentrygps/Cargo.toml @@ -21,10 +21,11 @@ maintenance = { status = "actively-developed" } [dependencies] toml = "0.4" -toml-query = "0.7" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } serde_derive = "1" serde = "1" -error-chain = "0.12" +failure = "0.1" +failure_derive = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/entry/libimagentrygps/src/entry.rs b/lib/entry/libimagentrygps/src/entry.rs index d6eb4be7..8022e368 100644 --- a/lib/entry/libimagentrygps/src/entry.rs +++ b/lib/entry/libimagentrygps/src/entry.rs @@ -17,9 +17,6 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error::Result; -use error::GPSErrorKind as GPSEK; -use error::ResultExt; use types::*; use libimagstore::store::Entry; @@ -27,6 +24,9 @@ use libimagstore::store::Entry; use toml_query::read::TomlValueReadExt; use toml_query::insert::TomlValueInsertExt; use toml_query::delete::TomlValueDeleteExt; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::Error; pub trait GPSEntry { @@ -60,11 +60,11 @@ impl GPSEntry for Entry { self.get_header_mut() .insert("gps.coordinates", c.into()) .map(|_| ()) - .chain_err(|| GPSEK::HeaderWriteError) + .map_err(Error::from) } fn get_coordinates(&self) -> Result> { - match self.get_header().read("gps.coordinates").chain_err(|| GPSEK::HeaderWriteError)? { + match self.get_header().read("gps.coordinates").map_err(Error::from)? { Some(hdr) => Coordinates::from_value(hdr).map(Some), None => Ok(None), } @@ -88,7 +88,9 @@ impl GPSEntry for Entry { let hdr = self.get_header_mut(); for pattern in patterns.iter() { - let _ = hdr.delete(pattern).chain_err(|| GPSEK::HeaderWriteError)?; + let _ = hdr.delete(pattern) + .map_err(Error::from) + .context("Error writing header")?; } match coordinates { diff --git a/lib/entry/libimagentrygps/src/error.rs b/lib/entry/libimagentrygps/src/error.rs deleted file mode 100644 index 22f5a764..00000000 --- a/lib/entry/libimagentrygps/src/error.rs +++ /dev/null @@ -1,87 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - GPSError, GPSErrorKind, ResultExt, Result; - } - - errors { - StoreReadError { - description("Store read error") - display("Store read error") - } - - StoreWriteError { - description("Store write error") - display("Store write error") - } - - HeaderWriteError { - description("Couldn't write Header for annotation") - display("Couldn't write Header for annotation") - } - - HeaderReadError { - description("Couldn't read Header of Entry") - display("Couldn't read Header of Entry") - } - - HeaderTypeError { - description("Header field has unexpected type") - display("Header field has unexpected type") - } - - TypeError { - description("Type Error") - display("Type Error") - } - - DegreeMissing { - description("'degree' value missing") - display("'degree' value missing") - } - - MinutesMissing { - description("'minutes' value missing") - display("'minutes' value missing") - } - - SecondsMissing { - description("'seconds' value missing") - display("'seconds' value missing") - } - - LongitudeMissing { - description("'longitude' value missing") - display("'longitude' value missing") - } - - LatitudeMissing { - description("'latitude' value missing") - display("'latitude' value missing") - } - - NumberConversionError { - description("Cannot convert number to fit into variable") - display("Cannot convert number to fit into variable") - } - } -} - diff --git a/lib/entry/libimagentrygps/src/lib.rs b/lib/entry/libimagentrygps/src/lib.rs index 6343d693..15397ad5 100644 --- a/lib/entry/libimagentrygps/src/lib.rs +++ b/lib/entry/libimagentrygps/src/lib.rs @@ -36,7 +36,7 @@ extern crate toml; extern crate toml_query; #[macro_use] extern crate serde_derive; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagstore; extern crate libimagerror; @@ -45,6 +45,5 @@ extern crate libimagerror; extern crate env_logger; pub mod entry; -pub mod error; pub mod types; diff --git a/lib/entry/libimagentrygps/src/types.rs b/lib/entry/libimagentrygps/src/types.rs index 265539e7..9f44fc8c 100644 --- a/lib/entry/libimagentrygps/src/types.rs +++ b/lib/entry/libimagentrygps/src/types.rs @@ -23,10 +23,11 @@ use std::fmt::Formatter; use std::fmt::Result as FmtResult; use toml::Value; +use failure::Fallible as Result; +use failure::err_msg; +use failure::Error; -use error::GPSErrorKind as GPSEK; -use error::GPSError as GPSE; -use error::Result; +use libimagerror::errors::ErrorMsg as EM; pub trait FromValue : Sized { fn from_value(v: &Value) -> Result; @@ -80,28 +81,28 @@ impl FromValue for GPSValue { fn from_value(v: &Value) -> Result { let int_to_appropriate_width = |v: &Value| { v.as_integer() - .ok_or(GPSE::from_kind(GPSEK::HeaderTypeError)) + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError)) }; match *v { Value::Table(ref map) => { Ok(GPSValue::new( map.get("degree") - .ok_or_else(|| GPSE::from_kind(GPSEK::DegreeMissing)) + .ok_or_else(|| Error::from(err_msg("Degree missing"))) .and_then(&int_to_appropriate_width)?, map .get("minutes") - .ok_or_else(|| GPSE::from_kind(GPSEK::MinutesMissing)) + .ok_or_else(|| Error::from(err_msg("Minutes missing"))) .and_then(&int_to_appropriate_width)?, map .get("seconds") - .ok_or_else(|| GPSE::from_kind(GPSEK::SecondsMissing)) + .ok_or_else(|| Error::from(err_msg("Seconds missing"))) .and_then(&int_to_appropriate_width)? )) } - _ => Err(GPSE::from_kind(GPSEK::TypeError)) + _ => Err(Error::from(EM::EntryHeaderTypeError)) } } @@ -151,15 +152,17 @@ impl Into for Coordinates { impl FromValue for Coordinates { fn from_value(v: &Value) -> Result { v.as_table() - .ok_or(GPSE::from_kind(GPSEK::TypeError)) + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError)) .and_then(|t| { let get = |m: &BTreeMap<_, _>, what: &'static str, ek| -> Result { - m.get(what).ok_or(GPSE::from_kind(ek)).and_then(GPSValue::from_value) + m.get(what) + .ok_or_else(|| Error::from(err_msg(ek))) + .and_then(GPSValue::from_value) }; Ok(Coordinates::new( - get(t, "longitude", GPSEK::LongitudeMissing)?, - get(t, "latitude", GPSEK::LatitudeMissing)? + get(t, "longitude", "Longitude missing")?, + get(t, "latitude", "Latitude missing")? )) }) } diff --git a/lib/entry/libimagentrylink/Cargo.toml b/lib/entry/libimagentrylink/Cargo.toml index e04d4f6c..18dbad0c 100644 --- a/lib/entry/libimagentrylink/Cargo.toml +++ b/lib/entry/libimagentrylink/Cargo.toml @@ -27,8 +27,9 @@ url = "1.5" sha-1 = "0.7" hex = "0.3" is-match = "0.1" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" +failure_derive = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/entry/libimagentrylink/src/error.rs b/lib/entry/libimagentrylink/src/error.rs deleted file mode 100644 index b6f88ee2..00000000 --- a/lib/entry/libimagentrylink/src/error.rs +++ /dev/null @@ -1,93 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -use libimagstore::storeid::StoreId; - -error_chain! { - types { - LinkError, LinkErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - UrlError(::url::ParseError); - } - - errors { - EntryHeaderReadError { - description("Error while reading an entry header") - display("Error while reading an entry header") - } - - EntryHeaderWriteError { - description("Error while writing an entry header") - display("Error while writing an entry header") - } - - ExistingLinkTypeWrong { - description("Existing link entry has wrong type") - display("Existing link entry has wrong type") - } - - LinkTargetDoesNotExist { - description("Link target does not exist in the store") - display("Link target does not exist in the store") - } - - LinkParserError { - description("Link cannot be parsed") - display("Link cannot be parsed") - } - - LinkParserFieldMissingError { - description("Link cannot be parsed: Field missing") - display("Link cannot be parsed: Field missing") - } - - LinkParserFieldTypeError { - description("Link cannot be parsed: Field type wrong") - display("Link cannot be parsed: Field type wrong") - } - - InternalConversionError { - description("Error while converting values internally") - display("Error while converting values internally") - } - - InvalidUri { - description("URI is not valid") - display("URI is not valid") - } - - DeadLink(from: StoreId, to: StoreId) { - description("Dead link") - display("Dead link from: {from} to: {to}", from = from, to = to) - } - - LinkHandlingError { - description("Error in link handling") - display("Error in link handling") - } - } -} - diff --git a/lib/entry/libimagentrylink/src/external.rs b/lib/entry/libimagentrylink/src/external.rs index b2b898ba..6b951d46 100644 --- a/lib/entry/libimagentrylink/src/external.rs +++ b/lib/entry/libimagentrylink/src/external.rs @@ -39,16 +39,18 @@ use libimagstore::store::Store; use libimagstore::storeid::StoreId; use libimagstore::storeid::IntoStoreId; use libimagutil::debug_result::*; +use libimagerror::errors::ErrorMsg as EM; use toml_query::read::TomlValueReadExt; use toml_query::read::TomlValueReadTypeExt; use toml_query::insert::TomlValueInsertExt; +use failure::Error; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::err_msg; -use error::LinkErrorKind as LEK; -use error::Result; use internal::InternalLinker; use module_path::ModuleEntryPath; -use error::ResultExt; use self::iter::*; @@ -70,14 +72,21 @@ impl Link for Entry { fn get_link_uri_from_filelockentry(&self) -> Result> { self.get_header() .read_string("links.external.content.url") - .chain_err(|| LEK::EntryHeaderReadError) + .map_err(Error::from) + .context(EM::EntryHeaderReadError) + .map_err(Error::from) .and_then(|opt| match opt { None => Ok(None), Some(ref s) => { debug!("Found url, parsing: {:?}", s); - Url::parse(&s[..]).chain_err(|| LEK::InvalidUri).map(Some) + Url::parse(&s[..]) + .map_err(Error::from) + .context(err_msg("Invalid URI")) + .map_err(Error::from) + .map(Some) }, }) + .map_err(Error::from) } fn get_url(&self) -> Result> { @@ -85,7 +94,9 @@ impl Link for Entry { None => Ok(None), Some(ref s) => Url::parse(&s[..]) .map(Some) - .chain_err(|| LEK::EntryHeaderReadError), + .map_err(Error::from) + .context(EM::EntryHeaderReadError) + .map_err(Error::from), } } @@ -125,7 +136,7 @@ pub mod iter { use internal::Link; use internal::iter::LinkIter; - use error::Result; + use failure::Fallible as Result; use url::Url; diff --git a/lib/entry/libimagentrylink/src/internal.rs b/lib/entry/libimagentrylink/src/internal.rs index a69995c9..6b0a34c2 100644 --- a/lib/entry/libimagentrylink/src/internal.rs +++ b/lib/entry/libimagentrylink/src/internal.rs @@ -25,15 +25,15 @@ use libimagstore::storeid::StoreId; use libimagstore::storeid::IntoStoreId; use libimagstore::store::Entry; use libimagstore::store::Store; -use libimagstore::store::Result as StoreResult; +use libimagerror::errors::ErrorMsg as EM; use toml_query::read::TomlValueReadExt; use toml_query::insert::TomlValueInsertExt; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; -use error::LinkErrorKind as LEK; -use error::LinkError as LE; -use error::ResultExt; -use error::Result; use self::iter::LinkIter; use self::iter::IntoValues; @@ -101,11 +101,15 @@ impl Link { fn to_value(&self) -> Result { match self { &Link::Id { link: ref s } => - s.to_str().map(Value::String).chain_err(|| LEK::InternalConversionError), + s.to_str() + .map(Value::String) + .context(EM::ConversionError) + .map_err(Error::from), &Link::Annotated { ref link, annotation: ref anno } => { link.to_str() .map(Value::String) - .chain_err(|| LEK::InternalConversionError) + .context(EM::ConversionError) + .map_err(Error::from) .map(|link| { let mut tab = BTreeMap::new(); @@ -148,7 +152,7 @@ impl Into for Link { } impl IntoStoreId for Link { - fn into_storeid(self) -> StoreResult { + fn into_storeid(self) -> Result { match self { Link::Id { link } => Ok(link), Link::Annotated { link, .. } => Ok(link), @@ -190,15 +194,15 @@ pub mod iter { use std::vec::IntoIter; use super::Link; - use error::LinkErrorKind as LEK; - use error::ResultExt; - use error::Result; - + use failure::Error; + use failure::Fallible as Result; + use failure::ResultExt; use toml::Value; use itertools::Itertools; use libimagstore::store::Store; use libimagstore::store::FileLockEntry; + use libimagerror::errors::ErrorMsg as EM; pub struct LinkIter(IntoIter); @@ -232,7 +236,7 @@ pub mod iter { .unique() .sorted() .into_iter() // Cannot sort toml::Value, hence uglyness here - .map(|link| link.to_value().chain_err(|| LEK::InternalConversionError)) + .map(|link| link.to_value().context(EM::ConversionError).map_err(Error::from)) .collect() } } @@ -393,7 +397,10 @@ impl InternalLinker for Entry { let res = self .get_header() .read("links.internal") - .chain_err(|| LEK::EntryHeaderReadError) + .map_err(Error::from) + .context(EM::EntryHeaderReadError) + .context(EM::EntryHeaderError) + .map_err(Error::from) .map(|r| r.cloned()); process_rw_result(res) } @@ -417,19 +424,18 @@ impl InternalLinker for Entry { let new_links = LinkIter::new(new_links) .into_values() .into_iter() - .fold(Ok(vec![]), |acc, elem| { + .fold(Ok(vec![]), |acc: Result>, elem| { acc.and_then(move |mut v| { - elem.chain_err(|| LEK::InternalConversionError) - .map(|e| { - v.push(e); - v - }) + v.push(elem.context(EM::ConversionError)?); + Ok(v) }) })?; let res = self .get_header_mut() .insert("links.internal", Value::Array(new_links)) - .chain_err(|| LEK::EntryHeaderReadError); + .map_err(Error::from) + .context(EM::EntryHeaderReadError) + .map_err(Error::from); process_rw_result(res) } @@ -464,9 +470,9 @@ 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)? { + match store.get(id).map_err(Error::from)? { Some(mut entry) => self.remove_internal_link(&mut entry)?, - None => return Err(LEK::LinkTargetDoesNotExist.into()), + None => return Err(err_msg("Link target does not exist")), } } @@ -500,20 +506,19 @@ fn add_internal_link_with_instance(this: &mut Entry, link: &mut Entry, instance: fn rewrite_links>(header: &mut Value, links: I) -> Result<()> { let links = links.into_values() .into_iter() - .fold(Ok(vec![]), |acc, elem| { + .fold(Ok(vec![]), |acc: Result>, elem| { acc.and_then(move |mut v| { - elem.chain_err(|| LEK::InternalConversionError) - .map(|e| { - v.push(e); - v - }) + v.push(elem.context(EM::ConversionError)?); + Ok(v) }) })?; debug!("Setting new link array: {:?}", links); let process = header .insert("links.internal", Value::Array(links)) - .chain_err(|| LEK::EntryHeaderReadError); + .map_err(Error::from) + .context(EM::EntryHeaderReadError) + .map_err(Error::from); process_rw_result(process).map(|_| ()) } @@ -527,13 +532,10 @@ fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> { .chain(LinkIter::new(vec![from.into()])) .into_values() .into_iter() - .fold(Ok(vec![]), |acc, elem| { + .fold(Ok(vec![]), |acc: Result>, elem| { acc.and_then(move |mut v| { - elem.chain_err(|| LEK::InternalConversionError) - .map(|e| { - v.push(e); - v - }) + v.push(elem.context(EM::ConversionError)?); + Ok(v) }) })?; debug!("Setting links in {:?}: {:?}", target.get_location(), links); @@ -541,7 +543,9 @@ fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> { let res = target .get_header_mut() .insert("links.internal", Value::Array(links)) - .chain_err(|| LEK::EntryHeaderReadError); + .map_err(Error::from) + .context(EM::EntryHeaderReadError) + .map_err(Error::from); process_rw_result(res).map(|_| ()) }) @@ -553,7 +557,7 @@ fn process_rw_result(links: Result>) -> Result { let links = match links { Err(e) => { debug!("RW action on store failed. Generating LinkError"); - return Err(e).chain_err(|| LEK::EntryHeaderReadError) + return Err(e).context(EM::EntryHeaderReadError).map_err(Error::from) }, Ok(None) => { debug!("We got no value from the header!"); @@ -562,14 +566,14 @@ fn process_rw_result(links: Result>) -> Result { Ok(Some(Value::Array(l))) => l, Ok(Some(_)) => { debug!("We expected an Array for the links, but there was a non-Array!"); - return Err(LEK::ExistingLinkTypeWrong.into()); + return Err(err_msg("Link type error")); } }; if !links.iter().all(|l| is_match!(*l, Value::String(_)) || is_match!(*l, Value::Table(_))) { debug!("At least one of the Values which were expected in the Array of links is not a String or a Table!"); debug!("Generating LinkError"); - return Err(LEK::ExistingLinkTypeWrong.into()); + return Err(err_msg("Existing Link type error")); } let links : Vec = links.into_iter() @@ -585,13 +589,13 @@ fn process_rw_result(links: Result>) -> Result { if !tab.contains_key("link") || !tab.contains_key("annotation") { debug!("Things missing... returning Error instance"); - Err(LE::from_kind(LEK::LinkParserError)) + Err(err_msg("Link parser error")) } else { let link = tab.remove("link") - .ok_or(LE::from_kind(LEK::LinkParserFieldMissingError))?; + .ok_or(err_msg("Link parser: field missing"))?; let anno = tab.remove("annotation") - .ok_or(LE::from_kind(LEK::LinkParserFieldMissingError))?; + .ok_or(err_msg("Link parser: Field missing"))?; debug!("Ok, here we go with building a Link::Annotated"); match (link, anno) { @@ -605,7 +609,7 @@ fn process_rw_result(links: Result>) -> Result { } }) }, - _ => Err(LE::from_kind(LEK::LinkParserFieldTypeError)), + _ => Err(err_msg("Link parser: Field type error")), } } } @@ -620,8 +624,11 @@ fn process_rw_result(links: Result>) -> Result { pub mod store_check { use libimagstore::store::Store; - use error::Result; - use error::ResultExt; + + use failure::ResultExt; + use failure::Fallible as Result; + use failure::Error; + use failure::err_msg; pub trait StoreLinkConsistentExt { fn check_link_consistency(&self) -> Result<()>; @@ -631,9 +638,6 @@ pub mod store_check { fn check_link_consistency(&self) -> Result<()> { use std::collections::HashMap; - use error::LinkErrorKind as LEK; - use error::LinkError as LE; - use error::Result as LResult; use internal::InternalLinker; use libimagstore::storeid::StoreId; @@ -660,9 +664,7 @@ pub mod store_check { .fold(Ok(HashMap::new()), |map, element| { map.and_then(|mut map| { debug!("Checking element = {:?}", element); - let entry = element?.ok_or_else(|| { - LE::from(String::from("TODO: Not yet handled")) - })?; + let entry = element?.ok_or_else(|| err_msg("TODO: Not yet handled"))?; debug!("Checking entry = {:?}", entry.get_location()); @@ -687,18 +689,18 @@ pub mod store_check { // Helper to check whethre all StoreIds in the network actually exists // // Because why not? - let all_collected_storeids_exist = |network: &HashMap| -> LResult<()> { + let all_collected_storeids_exist = |network: &HashMap| -> Result<()> { for (id, _) in network.iter() { if is_match!(self.get(id.clone()), Ok(Some(_))) { debug!("Exists in store: {:?}", id); if !id.exists()? { warn!("Does exist in store but not on FS: {:?}", id); - return Err(LE::from_kind(LEK::LinkTargetDoesNotExist)) + return Err(err_msg("Link target does not exist")) } } else { warn!("Does not exist in store: {:?}", id); - return Err(LE::from_kind(LEK::LinkTargetDoesNotExist)) + return Err(err_msg("Link target does not exist")) } } @@ -706,8 +708,10 @@ pub mod store_check { }; // Helper function to create a SLCECD::OneDirectionalLink error object - let mk_one_directional_link_err = |src: StoreId, target: StoreId| -> LE { - LE::from_kind(LEK::DeadLink(src, target)) + let mk_one_directional_link_err = |src: StoreId, target: StoreId| -> Error { + Error::from(format_err!("Dead link: {} -> {}", + src.local_display_string(), + target.local_display_string())) }; // Helper lambda to check whether the _incoming_ links of each entry actually also @@ -760,7 +764,8 @@ pub mod store_check { .and_then(|nw| { all_collected_storeids_exist(&nw) .map(|_| nw) - .chain_err(|| LEK::LinkHandlingError) + .context(err_msg("Link handling error")) + .map_err(Error::from) }) .and_then(|nw| { for (id, linking) in nw.iter() { diff --git a/lib/entry/libimagentrylink/src/lib.rs b/lib/entry/libimagentrylink/src/lib.rs index 366d53fe..72b144d6 100644 --- a/lib/entry/libimagentrylink/src/lib.rs +++ b/lib/entry/libimagentrylink/src/lib.rs @@ -43,7 +43,7 @@ extern crate url; extern crate sha1; extern crate hex; #[macro_use] extern crate is_match; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; #[cfg(test)] extern crate env_logger; @@ -54,7 +54,6 @@ extern crate libimagutil; module_entry_path_mod!("links"); -pub mod error; pub mod external; pub mod internal; diff --git a/lib/entry/libimagentrymarkdown/Cargo.toml b/lib/entry/libimagentrymarkdown/Cargo.toml index 9fa5e9d1..870cf808 100644 --- a/lib/entry/libimagentrymarkdown/Cargo.toml +++ b/lib/entry/libimagentrymarkdown/Cargo.toml @@ -23,8 +23,8 @@ maintenance = { status = "actively-developed" } log = "0.4.0" hoedown = "6.0.0" url = "1.5" -error-chain = "0.12" env_logger = "0.5" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/entry/libimagentrymarkdown/src/error.rs b/lib/entry/libimagentrymarkdown/src/error.rs deleted file mode 100644 index 1ca2af98..00000000 --- a/lib/entry/libimagentrymarkdown/src/error.rs +++ /dev/null @@ -1,66 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -use url::Url; - -use libimagstore::storeid::StoreId; - -error_chain! { - types { - MarkdownError, MarkdownErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - LinkError(::libimagentrylink::error::LinkError, ::libimagentrylink::error::LinkErrorKind); - RefError(::libimagentryref::error::RefError, ::libimagentryref::error::RefErrorKind); - } - - foreign_links { - UrlParserError(::url::ParseError); - } - - errors { - MarkdownRenderError { - description("Markdown render error") - display("Markdown render error") - } - - LinkParsingError { - description("Link parsing error") - display("Link parsing error") - } - - StoreGetError(id: StoreId) { - description("Failed to get entry from store") - display("Failed to get entry '{}' from store", id) - } - - UndecidableLinkType(s: String) { - description("Failed to qualify link type") - display("The Type of the link '{}' cannot be recognized", s) - } - - UrlProcessingError(u: Url) { - description("Failed to properly processing URL") - display("The URL '{:?}' could not be processed properly", u) - } - } -} - diff --git a/lib/entry/libimagentrymarkdown/src/html.rs b/lib/entry/libimagentrymarkdown/src/html.rs index f9be8082..342dfb94 100644 --- a/lib/entry/libimagentrymarkdown/src/html.rs +++ b/lib/entry/libimagentrymarkdown/src/html.rs @@ -21,9 +21,10 @@ use hoedown::{Markdown, Html as MdHtml}; use hoedown::renderer::html::Flags as HtmlFlags; use hoedown::renderer::Render; -use error::Result; -use error::MarkdownErrorKind; -use error::ResultExt; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; pub type HTML = String; @@ -33,11 +34,13 @@ pub fn to_html(buffer: &str) -> Result { html.render(&md) .to_str() .map(String::from) - .chain_err(|| MarkdownErrorKind::MarkdownRenderError) + .map_err(Error::from) + .context(err_msg("Markdown rendering error")) + .map_err(Error::from) } pub mod iter { - use error::Result; + use failure::Fallible as Result; use libimagstore::store::Entry; use super::HTML; use super::to_html; diff --git a/lib/entry/libimagentrymarkdown/src/lib.rs b/lib/entry/libimagentrymarkdown/src/lib.rs index 71bf9bf0..18b8d474 100644 --- a/lib/entry/libimagentrymarkdown/src/lib.rs +++ b/lib/entry/libimagentrymarkdown/src/lib.rs @@ -42,14 +42,12 @@ extern crate libimagerror; extern crate libimagentrylink; extern crate libimagentryref; extern crate libimagutil; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; #[macro_use] extern crate log; #[cfg(test)] extern crate env_logger; - -pub mod error; pub mod html; pub mod link; pub mod processor; diff --git a/lib/entry/libimagentrymarkdown/src/link.rs b/lib/entry/libimagentrymarkdown/src/link.rs index 6d377358..3c237d98 100644 --- a/lib/entry/libimagentrymarkdown/src/link.rs +++ b/lib/entry/libimagentrymarkdown/src/link.rs @@ -17,9 +17,10 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error::MarkdownErrorKind as MEK; -use error::ResultExt; -use error::Result; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::Error; +use failure::err_msg; use hoedown::renderer::Render; use hoedown::Buffer; @@ -38,7 +39,8 @@ impl Link { pub fn into_urllink(self) -> Result { Url::parse(&self.link[..]) .map(move |link| UrlLink { title: self.title, link: link, }) - .chain_err(|| MEK::LinkParsingError) + .context(err_msg("Link parsing error")) + .map_err(Error::from) } } diff --git a/lib/entry/libimagentrymarkdown/src/processor.rs b/lib/entry/libimagentrymarkdown/src/processor.rs index 5fddcd9e..15e3c65b 100644 --- a/lib/entry/libimagentrymarkdown/src/processor.rs +++ b/lib/entry/libimagentrymarkdown/src/processor.rs @@ -18,11 +18,10 @@ // use std::path::Path; -use std::result::Result as RResult; -use error::MarkdownError as ME; -use error::MarkdownErrorKind as MEK; -use error::*; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; use link::extract_links; use libimagentrylink::external::ExternalLinker; @@ -42,17 +41,15 @@ use url::Url; pub struct UniqueMarkdownRefGenerator; impl UniqueRefPathGenerator for UniqueMarkdownRefGenerator { - type Error = ME; - fn collection() -> &'static str { "ref" // we can only use this collection, as we don't know about context } - fn unique_hash>(path: A) -> RResult { - Sha512::unique_hash(path).map_err(ME::from) + fn unique_hash>(path: A) -> Result { + Sha512::unique_hash(path).map_err(Error::from) } - fn postprocess_storeid(sid: StoreId) -> RResult { + fn postprocess_storeid(sid: StoreId) -> Result { Ok(sid) // don't do anything } } @@ -142,7 +139,7 @@ impl LinkProcessor { store.retrieve(id)? } else { store.get(id.clone())? - .ok_or(ME::from_kind(MEK::StoreGetError(id)))? + .ok_or_else(|| Error::from(format_err!("Store get error: {}", id)))? }; let _ = entry.add_internal_link(&mut target)?; @@ -170,7 +167,9 @@ impl LinkProcessor { }, LinkQualification::Undecidable(e) => { // error - return Err(e).chain_err(|| MEK::UndecidableLinkType(link.link.clone())) + return Err(e) + .context(format_err!("Undecidable link type: {}", link.link.clone())) + .map_err(Error::from) }, } } @@ -185,7 +184,7 @@ enum LinkQualification { InternalLink, ExternalLink(Url), RefLink(Url), - Undecidable(ME), + Undecidable(Error), } impl LinkQualification { @@ -210,7 +209,7 @@ impl LinkQualification { LinkQualification::InternalLink }, - _ => LinkQualification::Undecidable(ME::from(e)), + _ => LinkQualification::Undecidable(Error::from(e)), } } } diff --git a/lib/entry/libimagentryref/Cargo.toml b/lib/entry/libimagentryref/Cargo.toml index e3cc11be..91e5d464 100644 --- a/lib/entry/libimagentryref/Cargo.toml +++ b/lib/entry/libimagentryref/Cargo.toml @@ -23,8 +23,8 @@ maintenance = { status = "actively-developed" } itertools = "0.7" log = "0.4.0" toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" sha-1 = { version = "0.7", optional = true } sha2 = { version = "0.7", optional = true } sha3 = { version = "0.7", optional = true } diff --git a/lib/entry/libimagentryref/src/error.rs b/lib/entry/libimagentryref/src/error.rs deleted file mode 100644 index 98fd735e..00000000 --- a/lib/entry/libimagentryref/src/error.rs +++ /dev/null @@ -1,71 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - RefError, RefErrorKind, ResultExt, Result; - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - TomlQueryError(::toml_query::error::Error, ::toml_query::error::ErrorKind); - EntryUtilError(::libimagentryutil::error::EntryUtilError, ::libimagentryutil::error::EntryUtilErrorKind); - } - - foreign_links { - Io(::std::io::Error); - Utf8Error(::std::string::FromUtf8Error); - TomlDeError(::toml::de::Error); - TomlSerError(::toml::ser::Error); - } - - errors { - HeaderTypeError(field: &'static str, expectedtype: &'static str) { - description("Header type error") - display("Header type error: '{}' should be {}", field, expectedtype) - } - - HeaderFieldMissingError(field: &'static str) { - description("Header field missing error") - display("Header field missing: {}", field) - } - - HeaderFieldWriteError { - description("Header field cannot be written") - display("Header field cannot be written") - } - - HeaderFieldReadError { - description("Header field cannot be read") - display("Header field cannot be read") - } - - HeaderFieldAlreadyExistsError { - description("Header field already exists, cannot override") - display("Header field already exists, cannot override") - } - - PathUTF8Error { - description("Path cannot be converted because of UTF8 Error") - display("Path cannot be converted because of UTF8 Error") - } - - } -} - diff --git a/lib/entry/libimagentryref/src/generators/base.rs b/lib/entry/libimagentryref/src/generators/base.rs index aea60b28..10b0b294 100644 --- a/lib/entry/libimagentryref/src/generators/base.rs +++ b/lib/entry/libimagentryref/src/generators/base.rs @@ -21,27 +21,26 @@ use std::path::Path; use libimagstore::storeid::StoreId; -use error::RefError; use refstore::UniqueRefPathGenerator; +use failure::Fallible as Result; + /// A base UniqueRefPathGenerator which must be overridden by the actual UniqueRefPathGenerator /// which is provided by this crate #[allow(dead_code)] pub struct Base; impl UniqueRefPathGenerator for Base { - type Error = RefError; - fn collection() -> &'static str { "ref" } - fn unique_hash>(_path: A) -> Result { + fn unique_hash>(_path: A) -> Result { // This has to be overridden panic!("Not overridden base functionality. This is a BUG!") } - fn postprocess_storeid(sid: StoreId) -> Result { + fn postprocess_storeid(sid: StoreId) -> Result { Ok(sid) // default implementation } } diff --git a/lib/entry/libimagentryref/src/generators/mod.rs b/lib/entry/libimagentryref/src/generators/mod.rs index 23f12f51..e6398e17 100644 --- a/lib/entry/libimagentryref/src/generators/mod.rs +++ b/lib/entry/libimagentryref/src/generators/mod.rs @@ -50,24 +50,22 @@ macro_rules! make_unique_ref_path_generator { ( $name:ident over $underlying:ty - => with error $errtype:ty => with collection name $collectionname:expr ) => { struct $name; impl $crate::refstore::UniqueRefPathGenerator for $name { - type Error = $errtype; fn collection() -> &'static str { $collectionname } - fn unique_hash>(path: A) -> Result { + fn unique_hash>(path: A) -> Result { $underlying::unique_hash(path) } fn postprocess_storeid(sid: ::libimagstore::storeid::StoreId) - -> Result<::libimagstore::storeid::StoreId, Self::Error> + -> Result<::libimagstore::storeid::StoreId> { Ok(sid) } @@ -77,7 +75,6 @@ macro_rules! make_unique_ref_path_generator { ( $name:ident over $underlying:ty - => with error $errtype:ty => with collection name $collectionname:expr => $impl:expr ) => { @@ -90,13 +87,13 @@ macro_rules! make_unique_ref_path_generator { $collectionname } - fn unique_hash>(path: A) -> Result { + fn unique_hash>(path: A) -> Result { debug!("Making unique hash for path: {:?}", path.as_ref()); $impl(path) } fn postprocess_storeid(sid: ::libimagstore::storeid::StoreId) - -> Result<::libimagstore::storeid::StoreId, Self::Error> + -> Result<::libimagstore::storeid::StoreId> { Ok(sid) } @@ -106,14 +103,12 @@ macro_rules! make_unique_ref_path_generator { ( pub $name:ident over $underlying:ty - => with error $errtype:ty => with collection name $collectionname:expr => $impl:expr ) => { make_unique_ref_path_generator!( pub $name over $underlying - => with error $errtype => with collection name $collectionname => $impl => |sid| { Ok(sid) } ); @@ -122,7 +117,6 @@ macro_rules! make_unique_ref_path_generator { ( pub $name:ident over $underlying:ty - => with error $errtype:ty => with collection name $collectionname:expr => $impl:expr => $postproc:expr @@ -130,19 +124,17 @@ macro_rules! make_unique_ref_path_generator { pub struct $name; impl $crate::refstore::UniqueRefPathGenerator for $name { - type Error = $errtype; - fn collection() -> &'static str { $collectionname } - fn unique_hash>(path: A) -> ::std::result::Result { + fn unique_hash>(path: A) -> ::failure::Fallible { debug!("Making unique hash for path: {:?}", path.as_ref()); $impl(path) } fn postprocess_storeid(sid: ::libimagstore::storeid::StoreId) - -> Result<::libimagstore::storeid::StoreId, Self::Error> + -> ::failure::Fallible<::libimagstore::storeid::StoreId> { $postproc(sid) } @@ -173,13 +165,10 @@ macro_rules! make_sha_mod { use std::fs::OpenOptions; use std::io::Read; - use error::RefError as RE; - use hex; make_unique_ref_path_generator! ( pub $hashname over generators::base::Base - => with error RE => with collection name "ref" => |path| { OpenOptions::new() @@ -187,7 +176,7 @@ macro_rules! make_sha_mod { .write(false) .create(false) .open(path) - .map_err(RE::from) + .map_err(::failure::Error::from) .and_then(|mut file| { let mut buffer = String::new(); let _ = file.read_to_string(&mut buffer)?; @@ -199,14 +188,14 @@ macro_rules! make_sha_mod { impl $hashname { /// Function which can be used by a wrapping UniqueRefPathGenerator to hash only N bytes. - pub fn hash_n_bytes>(path: A, n: usize) -> Result { + pub fn hash_n_bytes>(path: A, n: usize) -> ::failure::Fallible { debug!("Opening '{}' for hashing", path.as_ref().display()); OpenOptions::new() .read(true) .write(false) .create(false) .open(path) - .map_err(RE::from) + .map_err(::failure::Error::from) .and_then(|mut file| { let mut buffer = vec![0; n]; debug!("Allocated {} bytes", buffer.capacity()); diff --git a/lib/entry/libimagentryref/src/lib.rs b/lib/entry/libimagentryref/src/lib.rs index d22c04a7..0747c916 100644 --- a/lib/entry/libimagentryref/src/lib.rs +++ b/lib/entry/libimagentryref/src/lib.rs @@ -43,11 +43,10 @@ extern crate toml_query; #[macro_use] extern crate libimagstore; extern crate libimagerror; #[macro_use] extern crate libimagentryutil; -#[macro_use] extern crate error_chain; +extern crate failure; module_entry_path_mod!("ref"); -pub mod error; pub mod reference; pub mod refstore; diff --git a/lib/entry/libimagentryref/src/reference.rs b/lib/entry/libimagentryref/src/reference.rs index a02d48aa..d5e3b973 100644 --- a/lib/entry/libimagentryref/src/reference.rs +++ b/lib/entry/libimagentryref/src/reference.rs @@ -22,21 +22,20 @@ use std::path::Path; use std::path::PathBuf; -use std::result::Result as RResult; use libimagentryutil::isa::Is; use libimagentryutil::isa::IsKindHeaderPathProvider; use libimagstore::store::Entry; +use libimagerror::errors::ErrorMsg as EM; use toml::Value; use toml_query::read::TomlValueReadExt; use toml_query::delete::TomlValueDeleteExt; use toml_query::insert::TomlValueInsertExt; +use failure::Fallible as Result; +use failure::Error; use refstore::UniqueRefPathGenerator; -use error::Result; -use error::RefError as RE; -use error::RefErrorKind as REK; pub trait Ref { @@ -57,7 +56,7 @@ pub trait Ref { fn get_path(&self) -> Result; /// Check whether the referenced file still matches its hash - fn hash_valid(&self) -> RResult; + fn hash_valid(&self) -> Result; fn remove_ref(&mut self) -> Result<()>; @@ -84,15 +83,17 @@ impl Ref for Entry { /// Check whether the underlying object is actually a ref fn is_ref(&self) -> Result { - self.is::().map_err(From::from) + self.is::().map_err(Error::from) } fn get_hash(&self) -> Result<&str> { self.get_header() .read("ref.hash") - .map_err(RE::from)? - .ok_or_else(|| REK::HeaderFieldMissingError("ref.hash").into()) - .and_then(|v| v.as_str().ok_or_else(|| REK::HeaderTypeError("ref.hash", "string").into())) + .map_err(Error::from)? + .ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("ref.hash"))) + .and_then(|v| { + v.as_str().ok_or_else(|| Error::from(EM::EntryHeaderTypeError2("ref.hash", "string"))) + }) } fn make_ref>(&mut self, hash: String, path: P) -> Result<()> { @@ -100,7 +101,7 @@ impl Ref for Entry { .as_ref() .to_str() .map(String::from) - .ok_or_else(|| RE::from(REK::PathUTF8Error))?; + .ok_or_else(|| EM::UTF8Error)?; let _ = self.set_isflag::()?; let hdr = self.get_header_mut(); @@ -113,17 +114,20 @@ impl Ref for Entry { fn get_path(&self) -> Result { self.get_header() .read("ref.path") - .map_err(RE::from)? - .ok_or_else(|| REK::HeaderFieldMissingError("ref.path").into()) - .and_then(|v| v.as_str().ok_or_else(|| REK::HeaderTypeError("ref.path", "string").into())) + .map_err(Error::from)? + .ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("ref.path"))) + .and_then(|v| { + v.as_str() + .ok_or_else(|| EM::EntryHeaderTypeError2("ref.path", "string")) + .map_err(Error::from) + }) .map(PathBuf::from) } - fn hash_valid(&self) -> RResult { + fn hash_valid(&self) -> Result { self.get_path() .map(PathBuf::from) - .map_err(RE::from) - .map_err(RPG::Error::from) + .map_err(Error::from) .and_then(|pb| RPG::unique_hash(pb)) .and_then(|h| Ok(h == self.get_hash()?)) } diff --git a/lib/entry/libimagentryref/src/refstore.rs b/lib/entry/libimagentryref/src/refstore.rs index 6f57553b..6eadf944 100644 --- a/lib/entry/libimagentryref/src/refstore.rs +++ b/lib/entry/libimagentryref/src/refstore.rs @@ -24,26 +24,26 @@ use libimagstore::store::FileLockEntry; use libimagstore::store::Store; use libimagstore::storeid::StoreId; -use error::RefError as RE; use reference::Ref; +use failure::Fallible as Result; +use failure::Error; + /// A UniqueRefPathGenerator generates unique Pathes /// /// It is basically a functor which generates a StoreId from a &Path. /// For more information have a look at the documentation of RefStore. pub trait UniqueRefPathGenerator { - type Error: From; - /// The collection the `StoreId` should be created for fn collection() -> &'static str { "ref" } /// A function which should generate a unique string for a Path - fn unique_hash>(path: A) -> Result; + fn unique_hash>(path: A) -> Result; /// Postprocess the generated `StoreId` object - fn postprocess_storeid(sid: StoreId) -> Result { + fn postprocess_storeid(sid: StoreId) -> Result { Ok(sid) } } @@ -80,45 +80,43 @@ pub trait UniqueRefPathGenerator { /// pub trait RefStore<'a> { - fn get_ref>(&'a self, hash: H) -> Result>, RPG::Error>; - fn create_ref>(&'a self, path: A) -> Result, RPG::Error>; - fn retrieve_ref>(&'a self, path: A) -> Result, RPG::Error>; + fn get_ref>(&'a self, hash: H) -> Result>>; + fn create_ref>(&'a self, path: A) -> Result>; + fn retrieve_ref>(&'a self, path: A) -> Result>; } impl<'a> RefStore<'a> for Store { fn get_ref>(&'a self, hash: H) - -> Result>, RPG::Error> + -> Result>> { let sid = StoreId::new_baseless(PathBuf::from(format!("{}/{}", RPG::collection(), hash.as_ref()))) - .map_err(RE::from)?; + .map_err(Error::from)?; debug!("Getting: {:?}", sid); self.get(sid) - .map_err(RE::from) - .map_err(RPG::Error::from) + .map_err(Error::from) } fn create_ref>(&'a self, path: A) - -> Result, RPG::Error> + -> Result> { let hash = RPG::unique_hash(&path)?; let pathbuf = PathBuf::from(format!("{}/{}", RPG::collection(), hash)); - let sid = StoreId::new_baseless(pathbuf.clone()).map_err(RE::from)?; + let sid = StoreId::new_baseless(pathbuf.clone())?; debug!("Creating: {:?}", sid); self.create(sid) - .map_err(RE::from) + .map_err(Error::from) .and_then(|mut fle| { fle.make_ref(hash, path)?; Ok(fle) }) - .map_err(RPG::Error::from) } fn retrieve_ref>(&'a self, path: A) - -> Result, RPG::Error> + -> Result> { match self.get_ref::(RPG::unique_hash(path.as_ref())?)? { Some(r) => Ok(r), diff --git a/lib/entry/libimagentrytag/Cargo.toml b/lib/entry/libimagentrytag/Cargo.toml index 43ad925f..afc743a6 100644 --- a/lib/entry/libimagentrytag/Cargo.toml +++ b/lib/entry/libimagentrytag/Cargo.toml @@ -26,8 +26,8 @@ toml = "0.4" itertools = "0.7" is-match = "0.1" filters = "0.3" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/entry/libimagentrytag/src/error.rs b/lib/entry/libimagentrytag/src/error.rs deleted file mode 100644 index 46524167..00000000 --- a/lib/entry/libimagentrytag/src/error.rs +++ /dev/null @@ -1,48 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - TagError, TagErrorKind, ResultExt, Result; - } - - errors { - TagTypeError { - description("Entry Header Tag Type wrong") - display("Entry Header Tag Type wrong") - } - - HeaderReadError { - description("Error while reading entry header") - display("Error while reading entry header") - } - - HeaderWriteError { - description("Error while writing entry header") - display("Error while writing entry header") - } - - NotATag { - description("String is not a tag") - display("String is not a tag") - } - - } -} - diff --git a/lib/entry/libimagentrytag/src/lib.rs b/lib/entry/libimagentrytag/src/lib.rs index 6cfe7c8c..6d5f46e6 100644 --- a/lib/entry/libimagentrytag/src/lib.rs +++ b/lib/entry/libimagentrytag/src/lib.rs @@ -43,12 +43,11 @@ extern crate toml; extern crate toml_query; #[macro_use] extern crate is_match; extern crate filters; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; extern crate libimagstore; extern crate libimagerror; -pub mod error; pub mod tag; pub mod tagable; diff --git a/lib/entry/libimagentrytag/src/tag.rs b/lib/entry/libimagentrytag/src/tag.rs index a2a84a99..ac51d88d 100644 --- a/lib/entry/libimagentrytag/src/tag.rs +++ b/lib/entry/libimagentrytag/src/tag.rs @@ -17,6 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // +use std::result::Result; + use regex::Regex; pub type Tag = String; diff --git a/lib/entry/libimagentrytag/src/tagable.rs b/lib/entry/libimagentrytag/src/tagable.rs index e405e51b..ed688d5f 100644 --- a/lib/entry/libimagentrytag/src/tagable.rs +++ b/lib/entry/libimagentrytag/src/tagable.rs @@ -20,14 +20,15 @@ use itertools::Itertools; use libimagstore::store::Entry; +use libimagerror::errors::ErrorMsg as EM; use toml_query::read::TomlValueReadExt; use toml_query::insert::TomlValueInsertExt; -use error::TagErrorKind; -use error::TagError as TE; -use error::ResultExt; -use error::Result; +use failure::Error; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::err_msg; use tag::{Tag, TagSlice}; use tag::is_tag_str; @@ -50,23 +51,22 @@ impl Tagable for Value { fn get_tags(&self) -> Result> { self.read("tag.values") - .chain_err(|| TagErrorKind::HeaderReadError)? + .map_err(Error::from) + .context(EM::EntryHeaderReadError)? .map(|val| { debug!("Got Value of tags..."); val.as_array() .map(|tags| { debug!("Got Array of tags..."); if !tags.iter().all(|t| is_match!(*t, Value::String(_))) { - debug!("Got Array, T != String of tags: {:?}", tags); - return Err(TagErrorKind::TagTypeError.into()); + return Err(format_err!("Tag type error: Got Array where T is not a String: {:?}", tags)); } debug!("Got Array of tags..."); if tags.iter().any(|t| match *t { Value::String(ref s) => !is_tag_str(s).is_ok(), _ => unreachable!()}) { - debug!("At least one tag is not a valid tag string"); - return Err(TagErrorKind::NotATag.into()); + return Err(format_err!("At least one tag is not a valid tag string")); } Ok(tags.iter() @@ -86,21 +86,23 @@ impl Tagable for Value { fn set_tags(&mut self, ts: &[Tag]) -> Result<()> { if ts.iter().any(|tag| !is_tag_str(tag).is_ok()) { - debug!("Not a tag: '{}'", ts.iter().filter(|t| !is_tag_str(t).is_ok()).next().unwrap()); - return Err(TagErrorKind::NotATag.into()); + let not_tag = ts.iter().filter(|t| !is_tag_str(t).is_ok()).next().unwrap(); + return Err(format_err!("Not a tag: '{}'", not_tag)); } let a = ts.iter().unique().map(|t| Value::String(t.clone())).collect(); debug!("Setting tags = {:?}", a); self.insert("tag.values", Value::Array(a)) .map(|_| ()) - .chain_err(|| TagErrorKind::HeaderWriteError) + .map_err(|_| Error::from(EM::EntryHeaderWriteError)) } fn add_tag(&mut self, t: Tag) -> Result<()> { - if !is_tag_str(&t).map(|_| true).map_err(|_| TE::from_kind(TagErrorKind::NotATag))? { - debug!("Not a tag: '{}'", t); - return Err(TagErrorKind::NotATag.into()); + if !is_tag_str(&t).map(|_| true) + .map_err(|s| format_err!("{}", s)) + .context(err_msg("Not a tag"))? + { + return Err(format_err!("Not a tag: '{}'", t)); } self.get_tags() @@ -113,9 +115,12 @@ impl Tagable for Value { } fn remove_tag(&mut self, t: Tag) -> Result<()> { - if !is_tag_str(&t).map(|_| true).map_err(|_| TE::from_kind(TagErrorKind::NotATag))? { + if !is_tag_str(&t).map(|_| true) + .map_err(|s| format_err!("{}", s)) + .context(err_msg("Not a tag"))? + { debug!("Not a tag: '{}'", t); - return Err(TagErrorKind::NotATag.into()); + return Err(format_err!("Not a tag: '{}'", t)); } self.get_tags() @@ -127,10 +132,10 @@ impl Tagable for Value { } fn has_tag(&self, t: TagSlice) -> Result { - let tags = self.read("tag.values").chain_err(|| TagErrorKind::HeaderReadError)?; + let tags = self.read("tag.values").context(EM::EntryHeaderReadError)?; if !tags.iter().all(|t| is_match!(*t, &Value::String(_))) { - return Err(TagErrorKind::TagTypeError.into()); + return Err(err_msg("Tag type error")) } Ok(tags diff --git a/lib/entry/libimagentryutil/Cargo.toml b/lib/entry/libimagentryutil/Cargo.toml index 16774334..c8d6da20 100644 --- a/lib/entry/libimagentryutil/Cargo.toml +++ b/lib/entry/libimagentryutil/Cargo.toml @@ -21,9 +21,9 @@ maintenance = { status = "actively-developed" } [dependencies] toml = "0.4" -toml-query = "0.7" -error-chain = "0.12" +toml-query = { git = "https://github.com/matthiasbeyer/toml-query", branch = "failure" } filters = "0.3" +failure = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/entry/libimagentryutil/src/error.rs b/lib/entry/libimagentryutil/src/error.rs deleted file mode 100644 index 87b48a40..00000000 --- a/lib/entry/libimagentryutil/src/error.rs +++ /dev/null @@ -1,32 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - EntryUtilError, EntryUtilErrorKind, ResultExt, Result; - } - - foreign_links { - TomlQueryError(::toml_query::error::Error); - } - - errors { - } -} - diff --git a/lib/entry/libimagentryutil/src/isa.rs b/lib/entry/libimagentryutil/src/isa.rs index 0681a75f..1481da51 100644 --- a/lib/entry/libimagentryutil/src/isa.rs +++ b/lib/entry/libimagentryutil/src/isa.rs @@ -17,8 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error::EntryUtilError as EUE; -use error::Result; +use failure::Fallible as Result; +use failure::Error; use toml::Value; use toml_query::read::TomlValueReadTypeExt; @@ -41,8 +41,9 @@ use toml_query::insert::TomlValueInsertExt; /// # extern crate libimagstore; /// # #[macro_use] /// # extern crate libimagentryutil; +/// # extern crate failure; /// -/// # use libimagentryutil::error::Result as Result; +/// use failure::Fallible as Result; /// use libimagentryutil::isa::IsKindHeaderPathProvider; /// use libimagentryutil::isa::Is; /// @@ -76,16 +77,16 @@ impl Is for ::libimagstore::store::Entry { fn is(&self) -> Result { let field = T::kindflag_header_location(); - match self.get_header().read_bool(field)? { + match self.get_header().read_bool(field).map_err(Error::from)? { Some(b) => Ok(b), - None => Err(format!("Field {} not available", field)).map_err(EUE::from), + None => Err(format_err!("Field {} not available", field)), } } fn set_isflag(&mut self) -> Result<()> { self.get_header_mut() .insert(T::kindflag_header_location(), Value::Boolean(true)) - .map_err(EUE::from) + .map_err(Error::from) .map(|_| ()) } } diff --git a/lib/entry/libimagentryutil/src/lib.rs b/lib/entry/libimagentryutil/src/lib.rs index 544d1770..f484d829 100644 --- a/lib/entry/libimagentryutil/src/lib.rs +++ b/lib/entry/libimagentryutil/src/lib.rs @@ -38,12 +38,11 @@ extern crate filters; extern crate toml; extern crate toml_query; -#[macro_use] extern crate error_chain; +#[macro_use] extern crate failure; extern crate libimagstore; extern crate libimagerror; -pub mod error; pub mod isa; pub mod isincollection; pub mod iter; diff --git a/lib/entry/libimagentryview/Cargo.toml b/lib/entry/libimagentryview/Cargo.toml index 705e4804..635dfc80 100644 --- a/lib/entry/libimagentryview/Cargo.toml +++ b/lib/entry/libimagentryview/Cargo.toml @@ -22,7 +22,7 @@ maintenance = { status = "actively-developed" } [dependencies] log = "0.4.0" toml = "0.4" -error-chain = "0.12" +failure = "0.1" textwrap = "0.10" libimagrt = { version = "0.9.0", path = "../../../lib/core/libimagrt" } @@ -31,7 +31,6 @@ libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" libimagentryedit = { version = "0.9.0", path = "../../../lib/entry/libimagentryedit" } mdcat = { version = "0.8", optional = true } -failure = { version = "0.1", optional = true } [dependencies.pulldown-cmark] version = "^0.1" @@ -47,5 +46,5 @@ features = ["parsing", "assets", "dump-load"] [features] default = [ "markdownviewer" ] -markdownviewer = ["mdcat", "failure", "pulldown-cmark", "syntect"] +markdownviewer = ["mdcat", "pulldown-cmark", "syntect"] diff --git a/lib/entry/libimagentryview/src/builtin/editor.rs b/lib/entry/libimagentryview/src/builtin/editor.rs index c5cd7394..29d2d68a 100644 --- a/lib/entry/libimagentryview/src/builtin/editor.rs +++ b/lib/entry/libimagentryview/src/builtin/editor.rs @@ -24,9 +24,10 @@ use libimagrt::runtime::Runtime; use libimagentryedit::edit::edit_in_tmpfile; use viewer::Viewer; -use error::Result; -use error::ResultExt; -use error::ViewErrorKind as VEK; +use failure::Fallible as Result; +use failure::ResultExt; +use failure::Error; +use failure::err_msg; pub struct EditorView<'a>(&'a Runtime<'a>); @@ -41,7 +42,9 @@ impl<'a> Viewer for EditorView<'a> { where W: Write { let mut entry = e.to_str()?.clone().to_string(); - edit_in_tmpfile(self.0, &mut entry).chain_err(|| VEK::ViewError) + edit_in_tmpfile(self.0, &mut entry) + .context(err_msg("Error while viewing")) + .map_err(Error::from) } } diff --git a/lib/entry/libimagentryview/src/builtin/md.rs b/lib/entry/libimagentryview/src/builtin/md.rs index 630719e3..83d247e9 100644 --- a/lib/entry/libimagentryview/src/builtin/md.rs +++ b/lib/entry/libimagentryview/src/builtin/md.rs @@ -28,7 +28,8 @@ use syntect::parsing::SyntaxSet; use mdcat; use viewer::Viewer; -use error::Result; +use failure::Fallible as Result; +use failure::Error; pub struct MarkdownViewer<'a> { rt: &'a Runtime<'a>, @@ -66,8 +67,7 @@ impl<'a> Viewer for MarkdownViewer<'a> { base_dir, self.resource_access.clone(), syntax_set) - .map_err(|e| e.compat()) - .map_err(::error::ViewError::from) + .map_err(Error::from) } } diff --git a/lib/entry/libimagentryview/src/builtin/plain.rs b/lib/entry/libimagentryview/src/builtin/plain.rs index b276ed93..cb30a3db 100644 --- a/lib/entry/libimagentryview/src/builtin/plain.rs +++ b/lib/entry/libimagentryview/src/builtin/plain.rs @@ -22,7 +22,7 @@ use std::io::Write; use libimagstore::store::Entry; use viewer::Viewer; -use error::Result; +use failure::Fallible as Result; pub struct PlainViewer { show_header: bool diff --git a/lib/entry/libimagentryview/src/builtin/stdout.rs b/lib/entry/libimagentryview/src/builtin/stdout.rs index f74f6b14..5f5b93df 100644 --- a/lib/entry/libimagentryview/src/builtin/stdout.rs +++ b/lib/entry/libimagentryview/src/builtin/stdout.rs @@ -24,7 +24,7 @@ use libimagstore::store::Entry; use toml::ser::to_string; use viewer::Viewer; -use error::Result; +use failure::Fallible as Result; pub struct StdoutViewer { view_header: bool, diff --git a/lib/entry/libimagentryview/src/error.rs b/lib/entry/libimagentryview/src/error.rs deleted file mode 100644 index c549fe88..00000000 --- a/lib/entry/libimagentryview/src/error.rs +++ /dev/null @@ -1,62 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - ViewError, ViewErrorKind, ResultExt, Result; - } - - foreign_links { - Failure(::failure::Compat<::failure::Error>) #[cfg(feature = "markdownviewer")]; - IO(::std::io::Error); - } - - links { - StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind); - } - - errors { - Unknown { - description("Unknown view error") - display("Unknown view error") - } - - GlobError { - description("Error while glob()ing") - display("Error while glob()ing") - } - - PatternError { - description("Error in glob() pattern") - display("Error in glob() pattern") - } - - PatternBuildingError { - description("Could not build glob() pattern") - display("Could not build glob() pattern") - } - - ViewError { - description("Failed to start viewer") - display("Failed to start viewer") - } - - } -} - diff --git a/lib/entry/libimagentryview/src/lib.rs b/lib/entry/libimagentryview/src/lib.rs index 52f30a0f..19d40baa 100644 --- a/lib/entry/libimagentryview/src/lib.rs +++ b/lib/entry/libimagentryview/src/lib.rs @@ -36,15 +36,12 @@ )] extern crate toml; -#[macro_use] extern crate error_chain; extern crate textwrap; +extern crate failure; #[cfg(feature = "markdownviewer")] extern crate mdcat; -#[cfg(feature = "markdownviewer")] -extern crate failure; - #[cfg(feature = "markdownviewer")] extern crate pulldown_cmark; @@ -56,7 +53,6 @@ extern crate libimagrt; extern crate libimagerror; extern crate libimagentryedit; -pub mod error; pub mod builtin; pub mod viewer; diff --git a/lib/entry/libimagentryview/src/viewer.rs b/lib/entry/libimagentryview/src/viewer.rs index dc0194cd..7dc4c6c5 100644 --- a/lib/entry/libimagentryview/src/viewer.rs +++ b/lib/entry/libimagentryview/src/viewer.rs @@ -22,7 +22,7 @@ use std::ops::Deref; use libimagstore::store::Entry; -use error::Result; +use failure::Fallible as Result; pub trait Viewer { @@ -35,9 +35,7 @@ pub trait Viewer { W: Write { for entry in entries { - if let Err(e) = self.view_entry(entry.deref(), sink) { - return Err(e); - } + let _ = self.view_entry(entry.deref(), sink)?; } Ok(()) } diff --git a/lib/etc/libimaginteraction/Cargo.toml b/lib/etc/libimaginteraction/Cargo.toml index b4755787..b198afde 100644 --- a/lib/etc/libimaginteraction/Cargo.toml +++ b/lib/etc/libimaginteraction/Cargo.toml @@ -26,9 +26,10 @@ lazy_static = "1" log = "0.4.0" regex = "1" toml = "0.4" -error-chain = "0.12" handlebars = "1.0" serde_json = "1" +failure = "0.1" +failure_derive = "0.1" libimagstore = { version = "0.9.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.9.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/etc/libimaginteraction/src/ask.rs b/lib/etc/libimaginteraction/src/ask.rs index e2997391..0c6c55cd 100644 --- a/lib/etc/libimaginteraction/src/ask.rs +++ b/lib/etc/libimaginteraction/src/ask.rs @@ -24,13 +24,13 @@ use std::io::BufRead; use std::io::BufReader; use std::result::Result as RResult; -use error::InteractionErrorKind; -use error::ResultExt; -use error::Result; - use regex::Regex; use ansi_term::Colour::*; use interactor::*; +use failure::Error; +use failure::ResultExt; +use failure::Fallible as Result; +use failure::err_msg; /// Ask the user for a Yes/No answer. Optionally provide a default value. If none is provided, this /// keeps loop{}ing @@ -163,7 +163,8 @@ fn ask_string_(s: &str, pub fn ask_select_from_list(list: &[&str]) -> Result { pick_from_list(default_menu_cmd().as_mut(), list, "Selection: ") - .chain_err(|| InteractionErrorKind::Unknown) + .context(err_msg("Unknown interaction error")) + .map_err(Error::from) } /// Helper function to print a imag question string. The `question` argument may not contain a diff --git a/lib/etc/libimaginteraction/src/error.rs b/lib/etc/libimaginteraction/src/error.rs deleted file mode 100644 index efa84f1b..00000000 --- a/lib/etc/libimaginteraction/src/error.rs +++ /dev/null @@ -1,83 +0,0 @@ -// -// imag - the personal information management suite for the commandline -// Copyright (C) 2015-2018 Matthias Beyer and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - InteractionError, InteractionErrorKind, ResultExt, Result; - } - - errors { - Unknown { - description("Unknown Error") - display("Unknown Error") - } - - CLIError { - description("Error on commandline") - display("Error on commandline") - } - - IdMissingError { - description("Commandline: ID missing") - display("Commandline: ID missing") - } - - StoreIdParsingError { - description("Error while parsing StoreId") - display("Error while parsing StoreId") - } - - IdSelectingError { - description("Error while selecting id") - display("Error while selecting id") - } - - ConfigError { - description("Configuration error") - display("Configuration error") - } - - ConfigMissingError { - description("Configuration missing") - display("Configuration missing") - } - - ConfigTypeError { - description("Config Type Error") - display("Config Type Error") - } - - NoConfigError { - description("No configuration") - display("No configuration") - } - - ReadlineHistoryFileCreationError { - description("Could not create history file for readline") - display("Could not create history file for readline") - } - - ReadlineError { - description("Readline error") - display("Readline error") - } - - } -} - diff --git a/lib/etc/libimaginteraction/src/lib.rs b/lib/etc/libimaginteraction/src/lib.rs index 00db42d7..a2dc5d52 100644 --- a/lib/etc/libimaginteraction/src/lib.rs +++ b/lib/etc/libimaginteraction/src/lib.rs @@ -43,13 +43,12 @@ extern crate clap; extern crate toml; extern crate handlebars; extern crate serde_json; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagstore; extern crate libimagerror; pub mod ask; -pub mod error; pub mod filter; pub mod format; pub mod ui; diff --git a/lib/etc/libimaginteraction/src/readline.rs b/lib/etc/libimaginteraction/src/readline.rs index 6aaede95..1b29826f 100644 --- a/lib/etc/libimaginteraction/src/readline.rs +++ b/lib/etc/libimaginteraction/src/readline.rs @@ -17,10 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error::InteractionError as IE; -use error::InteractionErrorKind as IEK; -use error::ResultExt; +use failure::ResultExt; use toml::Value; use rustyline::{Config, Editor}; @@ -46,32 +44,32 @@ impl Readline { .as_str() .map(PathBuf::from) .ok_or(IE::from_kind(IEK::ConfigTypeError)) - .chain_err(|| IEK::ConfigError) - .chain_err(|| IEK::ReadlineError)?; + .context(IEK::ConfigError) + .context(IEK::ReadlineError)?; let histsize = histsize .as_int() .ok_or(IE::from_kind(IEK::ConfigTypeError)) - .chain_err(|| IEK::ConfigError) - .chain_err(|| IEK::ReadlineError)?; + .context(IEK::ConfigError) + .context(IEK::ReadlineError)?; let histigndups = histigndups .as_bool() .ok_or(IE::from_kind(IEK::ConfigTypeError)) - .chain_err(|| IEK::ConfigError) - .chain_err(|| IEK::ReadlineError)?; + .context(IEK::ConfigError) + .context(IEK::ReadlineError)?; let histignspace = histignspace .as_bool() .ok_or(IE::from_kind(IEK::ConfigTypeError)) - .chain_err(|| IEK::ConfigError) - .chain_err(|| IEK::ReadlineError)?; + .context(IEK::ConfigError) + .context(IEK::ReadlineError)?; let prompt = prompt .as_str() .ok_or(IE::from_kind(IEK::ConfigTypeError)) - .chain_err(|| IEK::ConfigError) - .chain_err(|| IEK::ReadlineError)?; + .context(IEK::ConfigError) + .context(IEK::ReadlineError)?; let config = Config::builder(). .max_history_size(histsize) @@ -83,10 +81,10 @@ impl Readline { if !histfile.exists() { let _ = File::create(histfile.clone()) - .chain_err(|| IEK::ReadlineHistoryFileCreationError)?; + .context(IEK::ReadlineHistoryFileCreationError)?; } - let _ = editor.load_history(&histfile).chain_err(|| ReadlineError)?; + let _ = editor.load_history(&histfile).context(ReadlineError)?; Ok(Readline { editor: editor, diff --git a/lib/etc/libimaginteraction/src/ui.rs b/lib/etc/libimaginteraction/src/ui.rs index 916dbebc..57bcb409 100644 --- a/lib/etc/libimaginteraction/src/ui.rs +++ b/lib/etc/libimaginteraction/src/ui.rs @@ -23,10 +23,8 @@ use clap::{Arg, ArgMatches}; use libimagstore::storeid::StoreId; -use error::InteractionError as IE; -use error::Result; -use error::InteractionErrorKind as IEK; -use error::ResultExt; +use failure::err_msg; +use failure::Fallible as Result; pub fn id_argument<'a, 'b>() -> Arg<'a, 'b> { Arg::with_name(id_argument_name()) @@ -52,14 +50,12 @@ pub fn id_argument_long() -> &'static str { pub fn get_id(matches: &ArgMatches) -> Result> { matches .values_of(id_argument_name()) - .ok_or(IE::from_kind(IEK::IdMissingError)) - .chain_err(|| IEK::CLIError) + .ok_or(err_msg("CLI error")) .and_then(|vals| { vals.into_iter() .fold(Ok(vec![]), |acc, elem| { acc.and_then(|mut v| { - let elem = StoreId::new_baseless(PathBuf::from(String::from(elem))); - let elem = elem.chain_err(|| IEK::StoreIdParsingError)?; + let elem = StoreId::new_baseless(PathBuf::from(String::from(elem)))?; v.push(elem); Ok(v) }) @@ -71,11 +67,10 @@ pub fn get_or_select_id(matches: &ArgMatches, store_path: &PathBuf) -> Result and contributors -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; version -// 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// - -error_chain! { - types { - NotificationError, NotificationErrorKind, ResultExt, Result; - } - - foreign_links { - NotifyError(::notify_rust::error::Error); - } - - errors { - Unknown { - description("Unknown Error") - display("Unknown Error") - } - } -} - diff --git a/lib/etc/libimagnotification/src/lib.rs b/lib/etc/libimagnotification/src/lib.rs index 6bf0f0e1..a64b3f43 100644 --- a/lib/etc/libimagnotification/src/lib.rs +++ b/lib/etc/libimagnotification/src/lib.rs @@ -34,11 +34,10 @@ )] extern crate notify_rust; -#[macro_use] extern crate error_chain; +extern crate failure; extern crate libimagerror; -pub mod error; pub mod notificator; pub mod result_notification; diff --git a/lib/etc/libimagnotification/src/notificator.rs b/lib/etc/libimagnotification/src/notificator.rs index 822dc92b..5ef97395 100644 --- a/lib/etc/libimagnotification/src/notificator.rs +++ b/lib/etc/libimagnotification/src/notificator.rs @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use error::Result; +use failure::Fallible as Result; /// A Notificator provides a function that can be called to notify about a certain object. /// @@ -34,7 +34,7 @@ pub mod default { use std::fmt::Debug; use std::fmt::Display; - use error::Result; + use failure::Fallible as Result; use notify_rust::Notification as RustNotification; use notify_rust::NotificationUrgency; diff --git a/lib/etc/libimagnotification/src/result_notification.rs b/lib/etc/libimagnotification/src/result_notification.rs index 8f700caa..5d33825f 100644 --- a/lib/etc/libimagnotification/src/result_notification.rs +++ b/lib/etc/libimagnotification/src/result_notification.rs @@ -31,12 +31,11 @@ pub mod err { use notify_rust::Notification as RustNotification; use notify_rust::NotificationUrgency; - use error::ResultExt; - use error::NotificationErrorKind as NEK; use notificator::default::Urgency; use notificator::default::Notification; use notificator::Notificator; - use error::Result; + use failure::Fallible as Result; + use failure::err_msg; #[derive(Debug, Default, Clone)] pub struct ErrorNotification(Notification, usize); @@ -64,7 +63,9 @@ pub mod err { n.summary("[Error]"); n.urgency(urgency); n.body(e.description()); - try!(n.finalize().show().map(|_| ()).chain_err(|| NEK::Unknown)); + let _ = n.finalize() + .show() + .map_err(|_| err_msg("Notification error"))?; if u > 0 { e.cause().map(|cause| trace_notify(urgency, cause, u - 1)); @@ -105,7 +106,8 @@ pub mod ok { use notificator::default::Notification; use notificator::Notificator; - use error::Result; + use failure::Fallible as Result; + use failure::err_msg; #[derive(Debug, Default, Clone)] pub struct OkNotification(Notification); @@ -127,8 +129,10 @@ pub mod ok { n.summary("[Ok]"); n.urgency(self.0.urgency.clone().into()); n.body(&"< >".to_owned()); - n.finalize().show().map(|_| ())?; - Ok(()) + n.finalize() + .show() + .map(|_| ()) + .map_err(|_| err_msg("Notification error")) } } diff --git a/lib/etc/libimagutil/src/testing.rs b/lib/etc/libimagutil/src/testing.rs index 70ec7915..d15ab383 100644 --- a/lib/etc/libimagutil/src/testing.rs +++ b/lib/etc/libimagutil/src/testing.rs @@ -50,9 +50,9 @@ macro_rules! make_mock_app { use clap::{App, ArgMatches}; use libimagrt::spec::CliSpec; use libimagrt::runtime::Runtime; - use libimagrt::error::RuntimeError; use libimagrt::configuration::InternalConfiguration; use toml::Value; + use failure::Error; #[derive(Clone)] struct MockLinkApp<'a> { @@ -95,8 +95,8 @@ macro_rules! make_mock_app { } #[allow(unused)] - pub fn generate_test_runtime<'a>(mut args: Vec<&'static str>) -> Result, RuntimeError> { - let mut cli_args = vec![$appname]; + pub fn generate_test_runtime<'a>(mut args: Vec<&'static str>) -> Result, Error> { + let mut cli_args = vec![$appname, "--rtp", "/tmp"]; cli_args.append(&mut args); @@ -106,7 +106,7 @@ macro_rules! make_mock_app { #[allow(unused)] pub fn reset_test_runtime<'a>(mut args: Vec<&'static str>, old_runtime: Runtime) - -> Result, RuntimeError> + -> Result, Error> { let mut cli_args = vec![$appname, "--rtp", "/tmp"];