summaryrefslogtreecommitdiffstats
path: root/bin/domain/imag-mail/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bin/domain/imag-mail/src/lib.rs')
-rw-r--r--bin/domain/imag-mail/src/lib.rs129
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, &notmuch_connection, &list_format, rt, &mut out, find_root)
- } else {
- process_nontree(iter, &mut i, &notmuch_connection, &list_format, rt, &mut out)
- }
+ process(iter, &mut i, &notmuch_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(&notmuch_connection);
- process_tree(iter, &mailstore, &notmuch_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, &notmuch_connection, &list_format, rt, &mut out)
+ }))
+ .collect::<Result<_>>()
} else {
- process_nontree(iter, &mut i, &notmuch_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, &notmuch_connection, &list_format, rt, &mut out)
}
}
}