diff options
Diffstat (limited to 'bin/domain/imag-mail/src/lib.rs')
-rw-r--r-- | bin/domain/imag-mail/src/lib.rs | 129 |
1 files changed, 31 insertions, 98 deletions
diff --git a/bin/domain/imag-mail/src/lib.rs b/bin/domain/imag-mail/src/lib.rs index 720f7a93..383a7ca8 100644 --- a/bin/domain/imag-mail/src/lib.rs +++ b/bin/domain/imag-mail/src/lib.rs @@ -51,21 +51,21 @@ extern crate libimagentryref; extern crate libimaginteraction; use std::io::Write; +use std::io::BufRead; use failure::Fallible as Result; use failure::err_msg; +use failure::Error; use clap::App; use resiter::AndThen; use resiter::IterInnerOkOrElse; use resiter::Filter; use resiter::Map; use handlebars::Handlebars; -use itertools::Itertools; use libimagmail::store::MailStore; use libimagmail::store::Sorting; use libimagmail::mail::Mail; -use libimagmail::store::MailStoreWithConnection; use libimagmail::notmuch::connection::NotmuchConnection; use libimagrt::runtime::Runtime; use libimagrt::application::ImagApplication; @@ -153,16 +153,13 @@ fn list(rt: &Runtime) -> Result<()> { let notmuch_connection = NotmuchConnection::open(notmuch_path)?; - let find_root = scmd.is_present("find-root"); - debug!("find_root: {}", find_root); - let mut out = rt.stdout(); let mut i = 0; /// Helper function for processing a tree /// /// This function implements the normal-style printing functionality (without "--tree"). - fn process_nontree<'a, I>(iter: I, + fn process<'a, I>(iter: I, i: &mut usize, conn: &NotmuchConnection, list_format: &Handlebars, @@ -171,7 +168,6 @@ fn list(rt: &Runtime) -> Result<()> { -> Result<()> where I: Iterator<Item = Result<FileLockEntry<'a>>> { - debug!("Processing non-tree"); iter.and_then_ok(|fle| { trace!("Loading: {}", fle.get_location()); let loaded = fle.load(&conn)? @@ -191,78 +187,6 @@ fn list(rt: &Runtime) -> Result<()> { .map(|_| ()) }; - /// Helper function for processing a tree - /// - /// This function implements the tree-style printing functionality ("--tree"). - fn process_tree<'a, I>(iter: I, - mailstore: &'a MailStoreWithConnection<'a>, - conn: &NotmuchConnection, - list_format: &Handlebars, - rt: &Runtime, - out: &mut dyn Write, - find_root: bool) - -> Result<()> - where I: Iterator<Item = Result<FileLockEntry<'a>>> - { - debug!("Processing tree"); - let iter = if find_root { - let iter = iter.and_then_ok(|fle| { - trace!("Loading: {}", fle.get_location()); - let id = fle - .load(conn)? - .ok_or_else(|| format_err!("Cannot load mail: {}", fle.get_location()))? - .parsed()? - .root_parent(&mailstore)? - .ok_or_else(|| format_err!("Failed to find root parent: {}", fle.get_location())) - .map(|p| p.get_id().clone()); - - drop(fle); - trace!("Loaded and parsed {:?} successfully", id); - id - }); - - Box::new(iter) as Box<dyn Iterator<Item = Result<String>>> - } else { - let iter = iter.and_then_ok(|fle| fle.get_cached_id()); - Box::new(iter) as Box<dyn Iterator<Item = Result<String>>> - }; - - trace!("Printing mailtrees now!"); - - // we have to collect here, so that all FLEs are drop()ed - let ids = iter.collect::<Result<Vec<String>>>()?; - trace!("ids = {:?}", ids); - - let mss = ids.into_iter() - .map(|id: String| mailstore.get_mailtree(&id)) - .collect::<Result<Vec<_>>>()?; - trace!("mss = {:?}", mss); - - mss.iter() - .map(|mailtree| mailtree.traverse()) - .flatten() - .unique_by(|tpl| tpl.1.clone()) - .sorted_by(|a, b| a.0.cmp(&b.0)) - .enumerate() - .map(|(i, (indent, mid))| { - let fle = mailstore.get_mail_by_id(&mid)?.ok_or_else(|| format_err!("Cannot find mail with id = {}", mid))?; - trace!("Printing: {}", fle.get_location()); - - let loaded = fle.load(&conn)? - .ok_or_else(|| format_err!("Mail not found: {}", fle.get_location()))?; - trace!("Loaded: {}", fle.get_location()); - - let parsed = loaded.parsed()?; - trace!("Parsed: {}", fle.get_location()); - - crate::util::list_mail(&parsed, i, indent, list_format, out)?; - trace!("Listed: {}", fle.get_location()); - rt.report_touched(fle.get_location()) - }) - .collect::<Result<Vec<()>>>() - .map(|_| ()) - } - if let Some(query) = scmd.value_of("query") { // Use notmuch to find mails @@ -276,28 +200,37 @@ fn list(rt: &Runtime) -> Result<()> { .into_iter() .map(Ok); - if tree { - process_tree(iter, &mailstore, ¬much_connection, &list_format, rt, &mut out, find_root) - } else { - process_nontree(iter, &mut i, ¬much_connection, &list_format, rt, &mut out) - } + process(iter, &mut i, ¬much_connection, &list_format, rt, &mut out) } else { - // use StoreIds to find mails - let iter = rt.ids::<crate::ui::PathProvider>()? - .ok_or_else(|| err_msg("No ids supplied"))? - .into_iter() - .map(Ok) - .into_get_iter(rt.store()) - .map_inner_ok_or_else(|| err_msg("Did not find one entry")) - .and_then_ok(|m| m.is_mail().map(|b| (b, m))) - .filter_ok(|tpl| tpl.0) - .map_ok(|tpl| tpl.1); - - if tree { + if scmd.is_present("query-from-stdin") { + let stdin = ::std::io::stdin(); + let mailstore = store.with_connection(¬much_connection); - process_tree(iter, &mailstore, ¬much_connection, &list_format, rt, &mut out, find_root) + stdin.lock() + .lines() + .map(|r| r.map_err(Error::from).and_then(|query| { + debug!("Querying: {}", query); + let it = mailstore.query(&query)?; + + debug!("Found: {:?}", it); + let it = it.into_iter().map(Ok); + + process(it, &mut i, ¬much_connection, &list_format, rt, &mut out) + })) + .collect::<Result<_>>() } else { - process_nontree(iter, &mut i, ¬much_connection, &list_format, rt, &mut out) + // use StoreIds to find mails + let iter = rt.ids::<crate::ui::PathProvider>()? + .ok_or_else(|| err_msg("No ids supplied"))? + .into_iter() + .map(Ok) + .into_get_iter(rt.store()) + .map_inner_ok_or_else(|| err_msg("Did not find one entry")) + .and_then_ok(|m| m.is_mail().map(|b| (b, m))) + .filter_ok(|tpl| tpl.0) + .map_ok(|tpl| tpl.1); + + process(iter, &mut i, ¬much_connection, &list_format, rt, &mut out) } } } |