/*
* meli - mailbox threading module.
*
* Copyright 2017 Manos Pitsidianakis
*
* This file is part of meli.
*
* meli is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* meli 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* e-mail threading (conversations)
*
* This module implements Jamie Zawinski's [threading algorithm](https://www.jwz.org/doc/threading.html). Quoted comments (/* " .. " */) are
* taken almost verbatim from the algorithm.
*
* The entry point of this module is the `Threads` struct and its `new` method. It contains
* `ThreadNodes` which are the nodes in the thread trees that might have messages associated with
* them. The root nodes (first messages in each thread) are stored in `root_set` and `tree`
* vectors. `Threads` has inner mutability since we need to sort without the user having mutable
* ownership.
*/
use crate::datetime::UnixTimestamp;
use crate::email::parser::BytesExt;
use crate::email::*;
mod iterators;
pub use iterators::*;
#[cfg(feature = "unicode_algorithms")]
use crate::text_processing::grapheme_clusters::*;
use uuid::Uuid;
use std::cell::RefCell;
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::iter::FromIterator;
use std::ops::Index;
use std::result::Result as StdResult;
use std::str::FromStr;
use std::string::ToString;
use std::sync::{Arc, RwLock};
use smallvec::SmallVec;
type Envelopes = Arc<RwLock<HashMap<EnvelopeHash, Envelope>>>;
macro_rules! uuid_hash_type {
($n:ident) => {
#[derive(PartialEq, Hash, Eq, Copy, Clone, Serialize, Deserialize, Default)]
pub struct $n(Uuid);
impl fmt::Debug for $n {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0.to_string())
}
}
impl fmt::Display for $n {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0.to_string