Merge branch 'imag-mail/main-return-result' into master

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2019-12-01 17:22:33 +01:00
commit 17d2e55bfa
2 changed files with 54 additions and 78 deletions

View File

@ -23,6 +23,7 @@ maintenance = { status = "actively-developed" }
log = "0.4.6" log = "0.4.6"
failure = "0.1.5" failure = "0.1.5"
indoc = "0.3.3" indoc = "0.3.3"
resiter = "0.4"
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" }

View File

@ -39,6 +39,7 @@ extern crate clap;
#[macro_use] extern crate failure; #[macro_use] extern crate failure;
extern crate toml_query; extern crate toml_query;
#[macro_use] extern crate indoc; #[macro_use] extern crate indoc;
extern crate resiter;
extern crate libimagrt; extern crate libimagrt;
extern crate libimagmail; extern crate libimagmail;
@ -51,13 +52,13 @@ use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
use failure::Fallible as Result; use failure::Fallible as Result;
use failure::err_msg;
use failure::Error;
use toml_query::read::TomlValueReadTypeExt; use toml_query::read::TomlValueReadTypeExt;
use clap::App; use clap::App;
use resiter::AndThen;
use resiter::IterInnerOkOrElse;
use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
use libimagmail::mail::Mail; use libimagmail::mail::Mail;
use libimagmail::store::MailStore; use libimagmail::store::MailStore;
use libimagmail::util; use libimagmail::util;
@ -79,25 +80,19 @@ mod ui;
pub enum ImagMail {} pub enum ImagMail {}
impl ImagApplication for ImagMail { impl ImagApplication for ImagMail {
fn run(rt: Runtime) -> Result<()> { fn run(rt: Runtime) -> Result<()> {
match rt.cli().subcommand_name().ok_or_else(|| err_msg("No subcommand called"))? {
if let Some(name) = rt.cli().subcommand_name() { "import-mail" => import_mail(&rt),
"list" => list(&rt),
debug!("Call {}", name); "mail-store" => mail_store(&rt),
match name { other => {
"import-mail" => import_mail(&rt), debug!("Unknown command");
"list" => list(&rt), if rt.handle_unknown_subcommand("imag-mail", other, rt.cli())?.success() {
"mail-store" => mail_store(&rt), Ok(())
other => { } else {
debug!("Unknown command"); Err(err_msg("Failed to handle unknown subcommand"))
let _ = rt.handle_unknown_subcommand("imag-mail", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
}
} }
} },
}
Ok(())
} }
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> { fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
@ -118,9 +113,9 @@ impl ImagApplication for ImagMail {
} }
fn import_mail(rt: &Runtime) { fn import_mail(rt: &Runtime) -> Result<()> {
let collection_name = get_ref_collection_name(rt).map_err_trace_exit_unwrap(); let collection_name = get_ref_collection_name(rt)?;
let refconfig = get_ref_config(rt, "imag-mail").map_err_trace_exit_unwrap(); let refconfig = get_ref_config(rt, "imag-mail")?;
let scmd = rt.cli().subcommand_matches("import-mail").unwrap(); let scmd = rt.cli().subcommand_matches("import-mail").unwrap();
let store = rt.store(); let store = rt.store();
@ -139,13 +134,14 @@ fn import_mail(rt: &Runtime) {
store.create_mail_from_path(path, &collection_name, &refconfig) store.create_mail_from_path(path, &collection_name, &refconfig)
} }
.map_info_str("Ok") .map_info_str("Ok")
.map_err_trace_exit_unwrap()
}) })
.for_each(|entry| rt.report_touched(entry.get_location()).unwrap_or_exit()); .and_then_ok(|e| rt.report_touched(e.get_location()).map_err(Error::from))
.collect::<Result<Vec<()>>>()
.map(|_| ())
} }
fn list(rt: &Runtime) { fn list(rt: &Runtime) -> Result<()> {
let refconfig = get_ref_config(rt, "imag-mail").map_err_trace_exit_unwrap(); let refconfig = get_ref_config(rt, "imag-mail")?;
let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe via clap let scmd = rt.cli().subcommand_matches("list").unwrap(); // safe via clap
let print_content = scmd.is_present("list-read"); let print_content = scmd.is_present("list-read");
@ -166,42 +162,26 @@ fn list(rt: &Runtime) {
fn list_mail<'a>(rt: &Runtime, fn list_mail<'a>(rt: &Runtime,
refconfig: &::libimagentryref::reference::Config, refconfig: &::libimagentryref::reference::Config,
m: &FileLockEntry<'a>, m: &FileLockEntry<'a>,
print_content: bool) { print_content: bool) -> Result<()> {
let id = match m.get_message_id(&refconfig) { let id = match m.get_message_id(&refconfig)? {
Ok(Some(f)) => f, Some(f) => f,
Ok(None) => "<no id>".to_owned(), None => "<no id>".to_owned(),
Err(e) => {
trace_error(&e);
"<error>".to_owned()
},
}; };
let from = match m.get_from(&refconfig) { let from = match m.get_from(&refconfig)? {
Ok(Some(f)) => f, Some(f) => f,
Ok(None) => "<no from>".to_owned(), None => "<no from>".to_owned(),
Err(e) => {
trace_error(&e);
"<error>".to_owned()
},
}; };
let to = match m.get_to(&refconfig) { let to = match m.get_to(&refconfig)? {
Ok(Some(f)) => f, Some(f) => f,
Ok(None) => "<no to>".to_owned(), None => "<no to>".to_owned(),
Err(e) => {
trace_error(&e);
"<error>".to_owned()
},
}; };
let subject = match m.get_subject(&refconfig) { let subject = match m.get_subject(&refconfig)? {
Ok(Some(f)) => f, Some(f) => f,
Ok(None) => "<no subject>".to_owned(), None => "<no subject>".to_owned(),
Err(e) => {
trace_error(&e);
"<error>".to_owned()
},
}; };
if print_content { if print_content {
@ -209,8 +189,7 @@ fn list(rt: &Runtime) {
let content = m.as_ref_with_hasher::<MailHasher>() let content = m.as_ref_with_hasher::<MailHasher>()
.get_path(&refconfig) .get_path(&refconfig)
.and_then(util::get_mail_text_content) .and_then(util::get_mail_text_content)?;
.map_err_trace_exit_unwrap();
writeln!(rt.stdout(), writeln!(rt.stdout(),
"Mail: {id}\nFrom: {from}\nTo: {to}\n{subj}\n---\n{content}\n---\n", "Mail: {id}\nFrom: {from}\nTo: {to}\n{subj}\n---\n{content}\n---\n",
@ -219,7 +198,7 @@ fn list(rt: &Runtime) {
subj = subject, subj = subject,
to = to, to = to,
content = content content = content
).to_exit_code().unwrap_or_exit(); )?;
} else { } else {
writeln!(rt.stdout(), writeln!(rt.stdout(),
"Mail: {id}\nFrom: {from}\nTo: {to}\n{subj}\n", "Mail: {id}\nFrom: {from}\nTo: {to}\n{subj}\n",
@ -227,41 +206,37 @@ fn list(rt: &Runtime) {
id = id, id = id,
subj = subject, subj = subject,
to = to to = to
).to_exit_code().unwrap_or_exit(); )?;
} }
rt.report_touched(m.get_location()).unwrap_or_exit(); rt.report_touched(m.get_location())?;
Ok(())
} }
if rt.ids_from_stdin() { if rt.ids_from_stdin() {
let iter = rt let iter = rt
.ids::<crate::ui::PathProvider>() .ids::<crate::ui::PathProvider>()?
.map_err_trace_exit_unwrap() .ok_or_else(|| err_msg("No ids supplied"))?
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter() .into_iter()
.map(Ok); .map(Ok);
StoreIdIterator::new(Box::new(iter)) StoreIdIterator::new(Box::new(iter))
} else { } else {
rt.store() rt.store()
.all_mails() .all_mails()?
.map_err_trace_exit_unwrap()
.into_storeid_iter() .into_storeid_iter()
} }
.map(|id| { debug!("Found: {:?}", id); id }) .inspect(|id| debug!("Found: {:?}", id))
.into_get_iter(rt.store()) .into_get_iter(rt.store())
.trace_unwrap_exit() .map_inner_ok_or_else(|| err_msg("Did not find one entry"))
.filter_map(|e| e) .and_then_ok(|m| list_mail(&rt, &refconfig, &m, print_content))
.for_each(|m| list_mail(&rt, &refconfig, &m, print_content)); .collect::<Result<Vec<_>>>()
.map(|_| ())
} }
fn mail_store(rt: &Runtime) { fn mail_store(rt: &Runtime) -> Result<()> {
let _ = rt.cli().subcommand_matches("mail-store").unwrap(); let _ = rt.cli().subcommand_matches("mail-store").unwrap();
error!("This feature is currently not implemented."); Err(format_err!("This feature is currently not implemented."))
unimplemented!()
} }
fn get_ref_collection_name(rt: &Runtime) -> Result<String> { fn get_ref_collection_name(rt: &Runtime) -> Result<String> {