summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2020-02-29 22:04:02 +0100
committerMatthias Beyer <mail@beyermatthias.de>2020-06-01 13:58:28 +0200
commit456647080e3b60b4421484a84c7fe53c1dbe94e7 (patch)
tree31d67bf3f2899203a52ff355ea0e549f19596942
parent69f747ee8fd7be9a18f867a492f632b867316258 (diff)
Remove mailtree module
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--lib/domain/libimagmail/src/lib.rs1
-rw-r--r--lib/domain/libimagmail/src/mailtree.rs346
-rw-r--r--lib/domain/libimagmail/src/store.rs15
3 files changed, 0 insertions, 362 deletions
diff --git a/lib/domain/libimagmail/src/lib.rs b/lib/domain/libimagmail/src/lib.rs
index f30c5e7c..c572ef92 100644
--- a/lib/domain/libimagmail/src/lib.rs
+++ b/lib/domain/libimagmail/src/lib.rs
@@ -59,7 +59,6 @@ module_entry_path_mod!("mail");
pub mod notmuch;
pub mod mail;
-pub mod mailtree;
pub mod store;
mod util;
diff --git a/lib/domain/libimagmail/src/mailtree.rs b/lib/domain/libimagmail/src/mailtree.rs
deleted file mode 100644
index 570fcda6..00000000
--- a/lib/domain/libimagmail/src/mailtree.rs
+++ /dev/null
@@ -1,346 +0,0 @@
-//
-// imag - the personal information management suite for the commandline
-// Copyright (C) 2015-2020 Matthias Beyer <mail@beyermatthias.de> 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 failure::Fallible as Result;
-use failure::ResultExt;
-use indextree::Arena;
-use indextree::NodeId;
-use indextree::Node;
-use itertools::Itertools;
-
-use crate::store::MailStoreWithConnection;
-use crate::mail::Mail;
-use crate::mail::LoadedMail;
-
-
-#[derive(Debug)]
-pub struct Mailtree {
- arena: Arena<String>,
- root: NodeId,
-}
-
-impl Mailtree {
- pub(crate) fn fill_from<'a>(store: &'a MailStoreWithConnection<'a>, root: LoadedMail)
- -> Result<Self>
- {
- let mut arena = Arena::<String>::new();
- let root = fill_arena_with(&mut arena, store, root)?;
- trace!("Arena = {:?}", root);
- Ok(Mailtree { arena, root })
- }
-
- pub fn root(&self) -> Option<&String> {
- self.arena.get(self.root).map(|node| node.get())
- }
-
- pub fn traverse(&self) -> Traverse {
- Traverse::with(self)
- }
-
- #[cfg(test)]
- fn fill_from_iter<I>(mut it: I) -> Option<(NodeId, Mailtree)>
- where I: Iterator<Item = String>
- {
- let mut arena = Arena::new();
- if let Some(rootdata) = it.next() {
- let root = arena.new_node(rootdata);
- let mut old_id = root.clone();
-
- while let Some(next_data) = it.next() {
- let next_id = arena.new_node(next_data);
- old_id.append(next_id.clone(), &mut arena);
-
- old_id = next_id;
- }
- Some((root, Mailtree { arena, root: root }))
- } else {
- None
- }
- }
-}
-
-fn fill_arena_with<'a>(arena: &mut Arena<String>, store: &'a MailStoreWithConnection<'a>, root: LoadedMail) -> Result<NodeId> {
- trace!("Filling arena starting at: {}", root.get_id());
-
- let root_id = root.get_id().clone();
- trace!("root_id = {:?}", root_id);
-
- let root_node = arena.new_node(root_id.clone());
- trace!("root_node = {:?}", root_node);
-
- let root_thread_id = root.get_thread_id().to_owned();
- trace!("root_thread_id = {:?}", root_thread_id);
- drop(root);
-
-
- let ids = store.connection().execute(|db| {
- let q = format!("thread:{}", root_thread_id);
- trace!("Executing query: {}", q);
- let query = db.create_query(&q)?;
- let r = query.search_threads()?
- .map(|thread| {
- trace!("Found thread: {}", thread.id());
- let messages = thread
- .messages()
- .map(|msg| {
- let id = msg.id();
- trace!("Found Message: {}", id);
-
- let id = id.into_owned();
- let new_node_id = arena.new_node(id.clone());
- root_node.append(new_node_id, arena);
- id
- })
- .collect::<Vec<String>>();
-
- trace!("Collected {} messages", messages.len());
- messages
- })
- .flat_map(|v| v.into_iter())
- .unique()
- .filter(|id| *id != root_id)
- .map(Ok)
- .collect::<Result<Vec<String>>>();
-
- trace!("Query '{:?}' resulted in: {:?}", query, r);
- r
- })?;
-
- trace!("IDs = {:?}", ids);
-
- ids
- .into_iter()
- .map(|id: String| {
- trace!("Trying to get: {:?}", id);
- let mail = store.get_mail_by_id(&id)
- .context("Getting mail by id")?
- .ok_or_else(|| format_err!("Cannot find mail for id {}", id))?;
- trace!("Fetched from store: {}", mail.get_location());
-
- let reply = mail
- .load(store.connection())?
- .ok_or_else(|| format_err!("Tried to load unavailable mail: {}", mail.get_location()))?;
- trace!("Loaded from store: {}", reply.get_id());
- Ok(())
- })
- .collect::<Result<Vec<_>>>()
- .map(|_| root_node)
-}
-
-/// A type for traversing the Mailtree
-///
-/// Implements an iterator that yields the Message IDs combined with an "indentation", which marks
-/// how deep the yielded node is in the tree.
-#[derive(Debug)]
-pub struct Traverse<'a> {
- tree: &'a Mailtree,
- next_node: Option<NodeId>,
- next_indent: usize,
-}
-
-impl<'a> Traverse<'a> {
- fn with(tree: &'a Mailtree) -> Self {
- Traverse {
- tree,
- next_node: Some(tree.root),
- next_indent: 0,
- }
- }
-
- fn get_node(&self, nodeid: NodeId) -> Option<String> {
- self.tree.arena.get(nodeid).map(|n| n.get()).map(ToOwned::to_owned)
- }
-
- fn get_current_node(&self) -> Option<&Node<String>> {
- self.next_node
- .and_then(|nodeid| self.tree.arena.get(nodeid))
- }
-
- fn current_node_next_sibling(&self) -> Option<NodeId> {
- self.get_current_node()
- .and_then(|node| node.next_sibling())
- }
-
- fn current_node_first_child(&self) -> Option<NodeId> {
- self.get_current_node()
- .and_then(|node| node.first_child())
- }
-
- fn current_node_parent(&self) -> Option<NodeId> {
- self.get_current_node()
- .and_then(|node| node.parent())
- }
-}
-
-impl<'a> Iterator for Traverse<'a> {
- type Item = (usize, String); // (Indention, Message Id)
-
- fn next(&mut self) -> Option<Self::Item> {
- if let Some(current_node) = self.next_node.and_then(|n| self.get_node(n)) {
- let current_indent = self.next_indent;
- trace!("Iterating: {:?}", self);
-
- if let Some(sibling) = self.current_node_next_sibling() {
- trace!("Sibling found: {:?}", sibling);
- // do not alter indent
- self.next_node = Some(sibling);
- return Some((current_indent, current_node));
- } else {
- trace!("No sibling found");
- if let Some(child) = self.current_node_first_child() {
- trace!("Child found: {:?}", child);
-
- // We have a child, make that the current node and return it
- self.next_indent += 1;
- self.next_node = Some(child);
- return Some((current_indent, current_node));
- } else {
- trace!("No child found");
- // We have no siblings and
- // We have no children
- // We might have to go back up one level
-
- if let Some(parent) = self.current_node_parent() {
- trace!("Parent found: {:?}", parent);
- // We have a parent
- if let Some(parents_sibling) = self.tree.arena.get(parent).and_then(|n| n.next_sibling()) {
- trace!("Parents sibling found: {:?}", parents_sibling);
- // And the parent has a sibling
- //
- // Make that the next current node and go from there
- self.next_indent -= 1;
- self.next_node = Some(parents_sibling);
- return Some((current_indent, current_node));
- } else {
- trace!("No parents sibling found");
- // We are the last node:
- // - We have no sibling
- // - We have no child
- // - Our parent has no sibling
- self.next_node = None;
- return Some((current_indent, current_node))
- }
- } else {
- trace!("No parent found");
- self.next_node = None;
- return Some((current_indent, current_node))
- }
- }
- }
- } else {
- return None;
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_traverse_with() {
- let data = String::from("test");
- let mut arena = Arena::new();
- let root = arena.new_node(data);
- let mailtree = Mailtree {
- arena,
- root: root.clone()
- };
-
- let t = Traverse::with(&mailtree);
-
- assert_eq!(t.next_node, Some(root));
- assert_eq!(t.next_indent, 0);
- }
-
- fn make_testing_mailtree(data: String) -> (NodeId, Mailtree) {
- let mut arena = Arena::new();
- let root = arena.new_node(data);
-
- (root.clone(), Mailtree { arena, root: root })
- }
-
- #[test]
- fn test_traverse_get_node() {
- let (root_id, mt) = make_testing_mailtree(String::from("test"));
- let t = Traverse::with(&mt);
- let root = t.get_node(root_id);
- assert!(root.is_some());
- assert_eq!(root.unwrap(), "test");
- }
-
- #[test]
- fn test_traverse_get_current_node() {
- let (_, mt) = make_testing_mailtree(String::from("test"));
- let t = Traverse::with(&mt);
- let node = t.get_current_node();
-
- assert!(node.is_some());
- let node = node.unwrap();
-
- assert_eq!(node.get(), "test");
- assert!(node.parent().is_none());
- assert!(node.first_child().is_none());
- assert!(node.last_child().is_none());
- assert!(node.previous_sibling().is_none());
- assert!(node.next_sibling().is_none());
- assert!(!node.is_removed());
- }
-
- #[test]
- fn test_traverse_current_node_next_sibling() {
- let (_, mt) = make_testing_mailtree(String::from("test"));
- let t = Traverse::with(&mt);
- assert!(t.current_node_next_sibling().is_none());
- }
-
- #[test]
- fn test_traverse_current_node_first_child() {
- let (_, mt) = make_testing_mailtree(String::from("test"));
- let t = Traverse::with(&mt);
- assert!(t.current_node_first_child().is_none());
- }
-
- #[test]
- fn test_traverse_current_node_parent() {
- let (_, mt) = make_testing_mailtree(String::from("test"));
- let t = Traverse::with(&mt);
- assert!(t.current_node_parent().is_none());
- }
-
-
- //
- // non-simple tests
- //
-
- #[test]
- fn test_iteration() {
- let data = ["1", "2", "3", "4"];
- let (_, mt) = Mailtree::fill_from_iter(data.iter().map(ToString::to_string)).unwrap();
- let mut t = Traverse::with(&mt);
-
- assert_eq!(t.next().unwrap(), (0, String::from("1")));
- assert_eq!(t.next().unwrap(), (1, String::from("2")));
- assert_eq!(t.next().unwrap(), (2, String::from("3")));
- assert_eq!(t.next().unwrap(), (3, String::from("4")));
- assert!(t.next().is_none());
- }
-
-}
-
diff --git a/lib/domain/libimagmail/src/store.rs b/lib/domain/libimagmail/src/store.rs
index 7a01dd1d..a2f420f7 100644
--- a/lib/domain/libimagmail/src/store.rs
+++ b/lib/domain/libimagmail/src/store.rs
@@ -35,7 +35,6 @@ use libimagentryutil::isa::Is;
use crate::notmuch::connection::NotmuchConnection;
use crate::mail::Mail;
use crate::mail::IsMail;
-use crate::mailtree::Mailtree;
pub trait MailStore<'a> {
fn with_connection(&'a self, c: &'a NotmuchConnection) -> MailStoreWithConnection<'a>;
@@ -117,20 +116,6 @@ impl<'a> MailStoreWithConnection<'a> {
self.get_entry_for_id(Cow::from(id))
}
- pub fn get_mailtree(&self, root_id: &str) -> Result<Mailtree> {
- trace!("Getting mail by id: {}", root_id);
- let root = self.get_mail_by_id(root_id)?
- .ok_or_else(|| format_err!("Cannot find root message: {}", root_id))?;
-
- trace!("Getting mail from connection: {:?}", root);
- let loaded_root = root.load(self.connection())?
- .ok_or_else(|| format_err!("Cannot load root message: {}", root_id))?;
-
- drop(root);
- trace!("Filling mailtree from: {:?}, {:?}", self, loaded_root);
- Mailtree::fill_from(self, loaded_root)
- }
-
fn create_entry_for_id(&self, id: Cow<str>) -> Result<FileLockEntry<'a>> {
let sid = crate::module_path::new_id(id.as_ref())?;
self.store