melib/backends: add collection() method to MailBackend
Keep track of the Collection state in the backend sidelazy_fetch
parent
eb8d29813c
commit
781a1d0e1b
|
@ -58,7 +58,7 @@ use self::maildir::MaildirType;
|
||||||
use self::mbox::MboxType;
|
use self::mbox::MboxType;
|
||||||
use super::email::{Envelope, EnvelopeHash, Flag};
|
use super::email::{Envelope, EnvelopeHash, Flag};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::BTreeSet;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -348,9 +348,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
|
||||||
mailbox_hash: MailboxHash,
|
mailbox_hash: MailboxHash,
|
||||||
) -> ResultFuture<()>;
|
) -> ResultFuture<()>;
|
||||||
|
|
||||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
fn collection(&self) -> crate::Collection;
|
||||||
None
|
|
||||||
}
|
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||||
|
|
||||||
|
|
|
@ -42,20 +42,21 @@ use crate::backends::{
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::collection::Collection;
|
||||||
use crate::conf::AccountSettings;
|
use crate::conf::AccountSettings;
|
||||||
use crate::connections::timeout;
|
use crate::connections::timeout;
|
||||||
use crate::email::{parser::BytesExt, *};
|
use crate::email::{parser::BytesExt, *};
|
||||||
use crate::error::{MeliError, Result, ResultIntoMeliError};
|
use crate::error::{MeliError, Result, ResultIntoMeliError};
|
||||||
use futures::lock::Mutex as FutureMutex;
|
use futures::lock::Mutex as FutureMutex;
|
||||||
use futures::stream::Stream;
|
use futures::stream::Stream;
|
||||||
use std::collections::{hash_map::DefaultHasher, BTreeMap};
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
pub type ImapNum = usize;
|
pub type ImapNum = usize;
|
||||||
|
@ -142,7 +143,7 @@ pub struct UIDStore {
|
||||||
msn_index: Arc<Mutex<HashMap<MailboxHash, Vec<UID>>>>,
|
msn_index: Arc<Mutex<HashMap<MailboxHash, Vec<UID>>>>,
|
||||||
|
|
||||||
byte_cache: Arc<Mutex<HashMap<UID, EnvelopeCache>>>,
|
byte_cache: Arc<Mutex<HashMap<UID, EnvelopeCache>>>,
|
||||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
collection: Collection,
|
||||||
|
|
||||||
/* Offline caching */
|
/* Offline caching */
|
||||||
uidvalidity: Arc<Mutex<HashMap<MailboxHash, UID>>>,
|
uidvalidity: Arc<Mutex<HashMap<MailboxHash, UID>>>,
|
||||||
|
@ -178,7 +179,7 @@ impl UIDStore {
|
||||||
msn_index: Default::default(),
|
msn_index: Default::default(),
|
||||||
byte_cache: Default::default(),
|
byte_cache: Default::default(),
|
||||||
mailboxes: Arc::new(FutureMutex::new(Default::default())),
|
mailboxes: Arc::new(FutureMutex::new(Default::default())),
|
||||||
tag_index: Arc::new(RwLock::new(Default::default())),
|
collection: Default::default(),
|
||||||
is_online: Arc::new(Mutex::new((
|
is_online: Arc::new(Mutex::new((
|
||||||
SystemTime::now(),
|
SystemTime::now(),
|
||||||
Err(MeliError::new("Account is uninitialised.")),
|
Err(MeliError::new("Account is uninitialised.")),
|
||||||
|
@ -710,7 +711,7 @@ impl MailBackend for ImapType {
|
||||||
/* Set flags/tags to true */
|
/* Set flags/tags to true */
|
||||||
let mut set_seen = false;
|
let mut set_seen = false;
|
||||||
let command = {
|
let command = {
|
||||||
let mut tag_lck = uid_store.tag_index.write().unwrap();
|
let mut tag_lck = uid_store.collection.tag_index.write().unwrap();
|
||||||
let mut cmd = format!("UID STORE {}", uids[0]);
|
let mut cmd = format!("UID STORE {}", uids[0]);
|
||||||
for uid in uids.iter().skip(1) {
|
for uid in uids.iter().skip(1) {
|
||||||
cmd = format!("{},{}", cmd, uid);
|
cmd = format!("{},{}", cmd, uid);
|
||||||
|
@ -859,10 +860,6 @@ impl MailBackend for ImapType {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
|
||||||
Some(self.uid_store.tag_index.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -871,6 +868,10 @@ impl MailBackend for ImapType {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collection(&self) -> Collection {
|
||||||
|
self.uid_store.collection.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn create_mailbox(
|
fn create_mailbox(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut path: String,
|
mut path: String,
|
||||||
|
@ -1773,7 +1774,7 @@ async fn fetch_hlpr(state: &mut FetchState) -> Result<Vec<Envelope>> {
|
||||||
}
|
}
|
||||||
env.set_references(value);
|
env.set_references(value);
|
||||||
}
|
}
|
||||||
let mut tag_lck = uid_store.tag_index.write().unwrap();
|
let mut tag_lck = uid_store.collection.tag_index.write().unwrap();
|
||||||
if let Some((flags, keywords)) = flags {
|
if let Some((flags, keywords)) = flags {
|
||||||
env.set_flags(*flags);
|
env.set_flags(*flags);
|
||||||
if !env.is_seen() {
|
if !env.is_seen() {
|
||||||
|
|
|
@ -239,7 +239,7 @@ mod sqlite3_m {
|
||||||
.entry(mailbox_hash)
|
.entry(mailbox_hash)
|
||||||
.and_modify(|entry| *entry = uidvalidity)
|
.and_modify(|entry| *entry = uidvalidity)
|
||||||
.or_insert(uidvalidity);
|
.or_insert(uidvalidity);
|
||||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||||
for f in to_str!(&flags).split('\0') {
|
for f in to_str!(&flags).split('\0') {
|
||||||
let hash = tag_hash!(f);
|
let hash = tag_hash!(f);
|
||||||
//debug!("hash {} flag {}", hash, &f);
|
//debug!("hash {} flag {}", hash, &f);
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl ImapConnection {
|
||||||
}
|
}
|
||||||
env.set_references(value);
|
env.set_references(value);
|
||||||
}
|
}
|
||||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||||
if let Some((flags, keywords)) = flags {
|
if let Some((flags, keywords)) = flags {
|
||||||
env.set_flags(*flags);
|
env.set_flags(*flags);
|
||||||
if !env.is_seen() {
|
if !env.is_seen() {
|
||||||
|
@ -469,7 +469,7 @@ impl ImapConnection {
|
||||||
}
|
}
|
||||||
env.set_references(value);
|
env.set_references(value);
|
||||||
}
|
}
|
||||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||||
if let Some((flags, keywords)) = flags {
|
if let Some((flags, keywords)) = flags {
|
||||||
env.set_flags(*flags);
|
env.set_flags(*flags);
|
||||||
if !env.is_seen() {
|
if !env.is_seen() {
|
||||||
|
|
|
@ -238,7 +238,7 @@ impl ImapConnection {
|
||||||
}
|
}
|
||||||
env.set_references(value);
|
env.set_references(value);
|
||||||
}
|
}
|
||||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||||
if let Some((flags, keywords)) = flags {
|
if let Some((flags, keywords)) = flags {
|
||||||
env.set_flags(*flags);
|
env.set_flags(*flags);
|
||||||
if !env.is_seen() {
|
if !env.is_seen() {
|
||||||
|
@ -381,7 +381,7 @@ impl ImapConnection {
|
||||||
}
|
}
|
||||||
env.set_references(value);
|
env.set_references(value);
|
||||||
}
|
}
|
||||||
let mut tag_lck = self.uid_store.tag_index.write().unwrap();
|
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||||
if let Some((flags, keywords)) = flags {
|
if let Some((flags, keywords)) = flags {
|
||||||
env.set_flags(*flags);
|
env.set_flags(*flags);
|
||||||
if !env.is_seen() {
|
if !env.is_seen() {
|
||||||
|
|
|
@ -388,7 +388,7 @@ pub async fn examine_updates(
|
||||||
}
|
}
|
||||||
env.set_references(value);
|
env.set_references(value);
|
||||||
}
|
}
|
||||||
let mut tag_lck = uid_store.tag_index.write().unwrap();
|
let mut tag_lck = uid_store.collection.tag_index.write().unwrap();
|
||||||
if let Some((flags, keywords)) = flags {
|
if let Some((flags, keywords)) = flags {
|
||||||
env.set_flags(*flags);
|
env.set_flags(*flags);
|
||||||
if !env.is_seen() {
|
if !env.is_seen() {
|
||||||
|
|
|
@ -23,12 +23,13 @@ use crate::backends::*;
|
||||||
use crate::conf::AccountSettings;
|
use crate::conf::AccountSettings;
|
||||||
use crate::email::*;
|
use crate::email::*;
|
||||||
use crate::error::{MeliError, Result};
|
use crate::error::{MeliError, Result};
|
||||||
|
use crate::Collection;
|
||||||
use futures::lock::Mutex as FutureMutex;
|
use futures::lock::Mutex as FutureMutex;
|
||||||
use isahc::config::RedirectPolicy;
|
use isahc::config::RedirectPolicy;
|
||||||
use isahc::prelude::HttpClient;
|
use isahc::prelude::HttpClient;
|
||||||
use isahc::ResponseExt;
|
use isahc::ResponseExt;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::collections::{hash_map::DefaultHasher, BTreeMap, HashMap, HashSet};
|
use std::collections::{hash_map::DefaultHasher, HashMap, HashSet};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -183,7 +184,7 @@ pub struct Store {
|
||||||
pub id_store: Arc<Mutex<HashMap<EnvelopeHash, Id<EmailObject>>>>,
|
pub id_store: Arc<Mutex<HashMap<EnvelopeHash, Id<EmailObject>>>>,
|
||||||
pub reverse_id_store: Arc<Mutex<HashMap<Id<EmailObject>, EnvelopeHash>>>,
|
pub reverse_id_store: Arc<Mutex<HashMap<Id<EmailObject>, EnvelopeHash>>>,
|
||||||
pub blob_id_store: Arc<Mutex<HashMap<EnvelopeHash, Id<BlobObject>>>>,
|
pub blob_id_store: Arc<Mutex<HashMap<EnvelopeHash, Id<BlobObject>>>>,
|
||||||
pub tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
pub collection: Collection,
|
||||||
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, JmapMailbox>>>,
|
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, JmapMailbox>>>,
|
||||||
pub mailboxes_index: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
|
pub mailboxes_index: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
|
||||||
pub mailbox_state: Arc<Mutex<State<MailboxObject>>>,
|
pub mailbox_state: Arc<Mutex<State<MailboxObject>>>,
|
||||||
|
@ -194,7 +195,7 @@ pub struct Store {
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
pub fn add_envelope(&self, obj: EmailObject) -> Envelope {
|
pub fn add_envelope(&self, obj: EmailObject) -> Envelope {
|
||||||
let mut tag_lck = self.tag_index.write().unwrap();
|
let mut tag_lck = self.collection.tag_index.write().unwrap();
|
||||||
let tags = obj
|
let tags = obj
|
||||||
.keywords()
|
.keywords()
|
||||||
.keys()
|
.keys()
|
||||||
|
@ -483,10 +484,6 @@ impl MailBackend for JmapType {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
|
||||||
Some(self.store.tag_index.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -495,6 +492,10 @@ impl MailBackend for JmapType {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collection(&self) -> Collection {
|
||||||
|
self.store.collection.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn search(
|
fn search(
|
||||||
&self,
|
&self,
|
||||||
q: crate::search::Query,
|
q: crate::search::Query,
|
||||||
|
@ -753,7 +754,7 @@ impl MailBackend for JmapType {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut tag_index_lck = store.tag_index.write().unwrap();
|
let mut tag_index_lck = store.collection.tag_index.write().unwrap();
|
||||||
for (flag, value) in flags.iter() {
|
for (flag, value) in flags.iter() {
|
||||||
match flag {
|
match flag {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
|
@ -841,12 +842,12 @@ impl JmapType {
|
||||||
online_status,
|
online_status,
|
||||||
event_consumer,
|
event_consumer,
|
||||||
is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)),
|
is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)),
|
||||||
|
collection: Collection::default(),
|
||||||
|
|
||||||
byte_cache: Default::default(),
|
byte_cache: Default::default(),
|
||||||
id_store: Default::default(),
|
id_store: Default::default(),
|
||||||
reverse_id_store: Default::default(),
|
reverse_id_store: Default::default(),
|
||||||
blob_id_store: Default::default(),
|
blob_id_store: Default::default(),
|
||||||
tag_index: Default::default(),
|
|
||||||
mailboxes: Default::default(),
|
mailboxes: Default::default(),
|
||||||
mailboxes_index: Default::default(),
|
mailboxes_index: Default::default(),
|
||||||
mailbox_state: Default::default(),
|
mailbox_state: Default::default(),
|
||||||
|
|
|
@ -25,6 +25,7 @@ use crate::conf::AccountSettings;
|
||||||
use crate::email::{Envelope, EnvelopeHash, Flag};
|
use crate::email::{Envelope, EnvelopeHash, Flag};
|
||||||
use crate::error::{ErrorKind, MeliError, Result};
|
use crate::error::{ErrorKind, MeliError, Result};
|
||||||
use crate::shellexpand::ShellExpandTrait;
|
use crate::shellexpand::ShellExpandTrait;
|
||||||
|
use crate::Collection;
|
||||||
use futures::prelude::Stream;
|
use futures::prelude::Stream;
|
||||||
|
|
||||||
extern crate notify;
|
extern crate notify;
|
||||||
|
@ -109,6 +110,7 @@ pub struct MaildirType {
|
||||||
mailbox_index: Arc<Mutex<HashMap<EnvelopeHash, MailboxHash>>>,
|
mailbox_index: Arc<Mutex<HashMap<EnvelopeHash, MailboxHash>>>,
|
||||||
hash_indexes: HashIndexes,
|
hash_indexes: HashIndexes,
|
||||||
event_consumer: BackendEventConsumer,
|
event_consumer: BackendEventConsumer,
|
||||||
|
collection: Collection,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,6 +1005,10 @@ impl MailBackend for MaildirType {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collection(&self) -> Collection {
|
||||||
|
self.collection.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn create_mailbox(
|
fn create_mailbox(
|
||||||
&mut self,
|
&mut self,
|
||||||
new_path: String,
|
new_path: String,
|
||||||
|
@ -1236,6 +1242,7 @@ impl MaildirType {
|
||||||
hash_indexes: Arc::new(Mutex::new(hash_indexes)),
|
hash_indexes: Arc::new(Mutex::new(hash_indexes)),
|
||||||
mailbox_index: Default::default(),
|
mailbox_index: Default::default(),
|
||||||
event_consumer,
|
event_consumer,
|
||||||
|
collection: Default::default(),
|
||||||
path: root_path,
|
path: root_path,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::backends::*;
|
use crate::backends::*;
|
||||||
|
use crate::collection::Collection;
|
||||||
use crate::conf::AccountSettings;
|
use crate::conf::AccountSettings;
|
||||||
use crate::email::parser::BytesExt;
|
use crate::email::parser::BytesExt;
|
||||||
use crate::email::*;
|
use crate::email::*;
|
||||||
|
@ -708,6 +709,7 @@ impl<'a> Iterator for MessageIterator<'a> {
|
||||||
pub struct MboxType {
|
pub struct MboxType {
|
||||||
account_name: String,
|
account_name: String,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
|
collection: Collection,
|
||||||
mailbox_index: Arc<Mutex<HashMap<EnvelopeHash, MailboxHash>>>,
|
mailbox_index: Arc<Mutex<HashMap<EnvelopeHash, MailboxHash>>>,
|
||||||
mailboxes: Arc<Mutex<HashMap<MailboxHash, MboxMailbox>>>,
|
mailboxes: Arc<Mutex<HashMap<MailboxHash, MboxMailbox>>>,
|
||||||
prefer_mbox_type: Option<MboxReader>,
|
prefer_mbox_type: Option<MboxReader>,
|
||||||
|
@ -1057,6 +1059,10 @@ impl MailBackend for MboxType {
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collection(&self) -> Collection {
|
||||||
|
self.collection.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! get_conf_val {
|
macro_rules! get_conf_val {
|
||||||
|
@ -1120,6 +1126,7 @@ impl MboxType {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
collection: Collection::default(),
|
||||||
mailbox_index: Default::default(),
|
mailbox_index: Default::default(),
|
||||||
mailboxes: Default::default(),
|
mailboxes: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,18 +32,18 @@ pub use operations::*;
|
||||||
mod connection;
|
mod connection;
|
||||||
pub use connection::*;
|
pub use connection::*;
|
||||||
|
|
||||||
use crate::backends::*;
|
|
||||||
use crate::conf::AccountSettings;
|
use crate::conf::AccountSettings;
|
||||||
use crate::email::*;
|
use crate::email::*;
|
||||||
use crate::error::{MeliError, Result, ResultIntoMeliError};
|
use crate::error::{MeliError, Result, ResultIntoMeliError};
|
||||||
|
use crate::{backends::*, Collection};
|
||||||
use futures::lock::Mutex as FutureMutex;
|
use futures::lock::Mutex as FutureMutex;
|
||||||
use futures::stream::Stream;
|
use futures::stream::Stream;
|
||||||
use std::collections::{hash_map::DefaultHasher, BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{hash_map::DefaultHasher, BTreeSet, HashMap, HashSet};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
pub type UID = usize;
|
pub type UID = usize;
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ pub struct UIDStore {
|
||||||
hash_index: Arc<Mutex<HashMap<EnvelopeHash, (UID, MailboxHash)>>>,
|
hash_index: Arc<Mutex<HashMap<EnvelopeHash, (UID, MailboxHash)>>>,
|
||||||
uid_index: Arc<Mutex<HashMap<(MailboxHash, UID), EnvelopeHash>>>,
|
uid_index: Arc<Mutex<HashMap<(MailboxHash, UID), EnvelopeHash>>>,
|
||||||
|
|
||||||
|
collection: Collection,
|
||||||
mailboxes: Arc<FutureMutex<HashMap<MailboxHash, NntpMailbox>>>,
|
mailboxes: Arc<FutureMutex<HashMap<MailboxHash, NntpMailbox>>>,
|
||||||
is_online: Arc<Mutex<(Instant, Result<()>)>>,
|
is_online: Arc<Mutex<(Instant, Result<()>)>>,
|
||||||
event_consumer: BackendEventConsumer,
|
event_consumer: BackendEventConsumer,
|
||||||
|
@ -97,6 +98,7 @@ impl UIDStore {
|
||||||
hash_index: Default::default(),
|
hash_index: Default::default(),
|
||||||
uid_index: Default::default(),
|
uid_index: Default::default(),
|
||||||
mailboxes: Arc::new(FutureMutex::new(Default::default())),
|
mailboxes: Arc::new(FutureMutex::new(Default::default())),
|
||||||
|
collection: Collection::new(),
|
||||||
is_online: Arc::new(Mutex::new((
|
is_online: Arc::new(Mutex::new((
|
||||||
Instant::now(),
|
Instant::now(),
|
||||||
Err(MeliError::new("Account is uninitialised.")),
|
Err(MeliError::new("Account is uninitialised.")),
|
||||||
|
@ -294,10 +296,6 @@ impl MailBackend for NntpType {
|
||||||
Err(MeliError::new("NNTP doesn't support deletion."))
|
Err(MeliError::new("NNTP doesn't support deletion."))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -306,6 +304,10 @@ impl MailBackend for NntpType {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collection(&self) -> Collection {
|
||||||
|
self.uid_store.collection.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn create_mailbox(
|
fn create_mailbox(
|
||||||
&mut self,
|
&mut self,
|
||||||
_path: String,
|
_path: String,
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::backends::*;
|
|
||||||
use crate::conf::AccountSettings;
|
use crate::conf::AccountSettings;
|
||||||
use crate::email::{Envelope, EnvelopeHash, Flag};
|
use crate::email::{Envelope, EnvelopeHash, Flag};
|
||||||
use crate::error::{MeliError, Result};
|
use crate::error::{MeliError, Result};
|
||||||
use crate::shellexpand::ShellExpandTrait;
|
use crate::shellexpand::ShellExpandTrait;
|
||||||
|
use crate::{backends::*, Collection};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::collections::{
|
use std::collections::{
|
||||||
hash_map::{DefaultHasher, HashMap},
|
hash_map::{DefaultHasher, HashMap},
|
||||||
|
@ -220,7 +220,7 @@ pub struct NotmuchDb {
|
||||||
mailboxes: Arc<RwLock<HashMap<MailboxHash, NotmuchMailbox>>>,
|
mailboxes: Arc<RwLock<HashMap<MailboxHash, NotmuchMailbox>>>,
|
||||||
index: Arc<RwLock<HashMap<EnvelopeHash, CString>>>,
|
index: Arc<RwLock<HashMap<EnvelopeHash, CString>>>,
|
||||||
mailbox_index: Arc<RwLock<HashMap<EnvelopeHash, SmallVec<[MailboxHash; 16]>>>>,
|
mailbox_index: Arc<RwLock<HashMap<EnvelopeHash, SmallVec<[MailboxHash; 16]>>>>,
|
||||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
collection: Collection,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
account_name: Arc<String>,
|
account_name: Arc<String>,
|
||||||
account_hash: AccountHash,
|
account_hash: AccountHash,
|
||||||
|
@ -358,7 +358,7 @@ impl NotmuchDb {
|
||||||
path,
|
path,
|
||||||
index: Arc::new(RwLock::new(Default::default())),
|
index: Arc::new(RwLock::new(Default::default())),
|
||||||
mailbox_index: Arc::new(RwLock::new(Default::default())),
|
mailbox_index: Arc::new(RwLock::new(Default::default())),
|
||||||
tag_index: Arc::new(RwLock::new(Default::default())),
|
collection: Collection::default(),
|
||||||
|
|
||||||
mailboxes: Arc::new(RwLock::new(mailboxes)),
|
mailboxes: Arc::new(RwLock::new(mailboxes)),
|
||||||
save_messages_to: None,
|
save_messages_to: None,
|
||||||
|
@ -510,7 +510,7 @@ impl MailBackend for NotmuchDb {
|
||||||
)?);
|
)?);
|
||||||
let index = self.index.clone();
|
let index = self.index.clone();
|
||||||
let mailbox_index = self.mailbox_index.clone();
|
let mailbox_index = self.mailbox_index.clone();
|
||||||
let tag_index = self.tag_index.clone();
|
let tag_index = self.collection.tag_index.clone();
|
||||||
let mailboxes = self.mailboxes.clone();
|
let mailboxes = self.mailboxes.clone();
|
||||||
let v: Vec<CString>;
|
let v: Vec<CString>;
|
||||||
{
|
{
|
||||||
|
@ -561,7 +561,7 @@ impl MailBackend for NotmuchDb {
|
||||||
let mailboxes = self.mailboxes.clone();
|
let mailboxes = self.mailboxes.clone();
|
||||||
let index = self.index.clone();
|
let index = self.index.clone();
|
||||||
let mailbox_index = self.mailbox_index.clone();
|
let mailbox_index = self.mailbox_index.clone();
|
||||||
let tag_index = self.tag_index.clone();
|
let tag_index = self.collection.tag_index.clone();
|
||||||
let event_consumer = self.event_consumer.clone();
|
let event_consumer = self.event_consumer.clone();
|
||||||
Ok(Box::pin(async move {
|
Ok(Box::pin(async move {
|
||||||
let new_revision_uuid = database.get_revision_uuid();
|
let new_revision_uuid = database.get_revision_uuid();
|
||||||
|
@ -586,13 +586,13 @@ impl MailBackend for NotmuchDb {
|
||||||
use notify::{watcher, RecursiveMode, Watcher};
|
use notify::{watcher, RecursiveMode, Watcher};
|
||||||
|
|
||||||
let account_hash = self.account_hash;
|
let account_hash = self.account_hash;
|
||||||
|
let collection = self.collection.clone();
|
||||||
let lib = self.lib.clone();
|
let lib = self.lib.clone();
|
||||||
let path = self.path.clone();
|
let path = self.path.clone();
|
||||||
let revision_uuid = self.revision_uuid.clone();
|
let revision_uuid = self.revision_uuid.clone();
|
||||||
let mailboxes = self.mailboxes.clone();
|
let mailboxes = self.mailboxes.clone();
|
||||||
let index = self.index.clone();
|
let index = self.index.clone();
|
||||||
let mailbox_index = self.mailbox_index.clone();
|
let mailbox_index = self.mailbox_index.clone();
|
||||||
let tag_index = self.tag_index.clone();
|
|
||||||
let event_consumer = self.event_consumer.clone();
|
let event_consumer = self.event_consumer.clone();
|
||||||
|
|
||||||
let (tx, rx) = std::sync::mpsc::channel();
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
@ -616,7 +616,7 @@ impl MailBackend for NotmuchDb {
|
||||||
mailboxes.clone(),
|
mailboxes.clone(),
|
||||||
index.clone(),
|
index.clone(),
|
||||||
mailbox_index.clone(),
|
mailbox_index.clone(),
|
||||||
tag_index.clone(),
|
collection.tag_index.clone(),
|
||||||
account_hash.clone(),
|
account_hash.clone(),
|
||||||
event_consumer.clone(),
|
event_consumer.clone(),
|
||||||
new_revision_uuid,
|
new_revision_uuid,
|
||||||
|
@ -651,7 +651,7 @@ impl MailBackend for NotmuchDb {
|
||||||
hash,
|
hash,
|
||||||
index: self.index.clone(),
|
index: self.index.clone(),
|
||||||
bytes: None,
|
bytes: None,
|
||||||
tag_index: self.tag_index.clone(),
|
collection: self.collection.clone(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +693,7 @@ impl MailBackend for NotmuchDb {
|
||||||
self.lib.clone(),
|
self.lib.clone(),
|
||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
let tag_index = self.tag_index.clone();
|
let collection = self.collection.clone();
|
||||||
let index = self.index.clone();
|
let index = self.index.clone();
|
||||||
|
|
||||||
Ok(Box::pin(async move {
|
Ok(Box::pin(async move {
|
||||||
|
@ -781,7 +781,11 @@ impl MailBackend for NotmuchDb {
|
||||||
for (f, v) in flags.iter() {
|
for (f, v) in flags.iter() {
|
||||||
if let (Err(tag), true) = (f, v) {
|
if let (Err(tag), true) = (f, v) {
|
||||||
let hash = tag_hash!(tag);
|
let hash = tag_hash!(tag);
|
||||||
tag_index.write().unwrap().insert(hash, tag.to_string());
|
collection
|
||||||
|
.tag_index
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.insert(hash, tag.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,8 +838,8 @@ impl MailBackend for NotmuchDb {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
fn collection(&self) -> Collection {
|
||||||
Some(self.tag_index.clone())
|
self.collection.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
@ -851,7 +855,7 @@ impl MailBackend for NotmuchDb {
|
||||||
struct NotmuchOp {
|
struct NotmuchOp {
|
||||||
hash: EnvelopeHash,
|
hash: EnvelopeHash,
|
||||||
index: Arc<RwLock<HashMap<EnvelopeHash, CString>>>,
|
index: Arc<RwLock<HashMap<EnvelopeHash, CString>>>,
|
||||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
collection: Collection,
|
||||||
database: Arc<DbConnection>,
|
database: Arc<DbConnection>,
|
||||||
bytes: Option<Vec<u8>>,
|
bytes: Option<Vec<u8>>,
|
||||||
lib: Arc<libloading::Library>,
|
lib: Arc<libloading::Library>,
|
||||||
|
|
|
@ -25,7 +25,7 @@ use smallvec::SmallVec;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
|
|
||||||
pub struct EnvelopeRef<'g> {
|
pub struct EnvelopeRef<'g> {
|
||||||
guard: RwLockReadGuard<'g, HashMap<EnvelopeHash, Envelope>>,
|
guard: RwLockReadGuard<'g, HashMap<EnvelopeHash, Envelope>>,
|
||||||
|
@ -64,8 +64,9 @@ pub struct Collection {
|
||||||
pub envelopes: Arc<RwLock<HashMap<EnvelopeHash, Envelope>>>,
|
pub envelopes: Arc<RwLock<HashMap<EnvelopeHash, Envelope>>>,
|
||||||
pub message_id_index: Arc<RwLock<HashMap<Vec<u8>, EnvelopeHash>>>,
|
pub message_id_index: Arc<RwLock<HashMap<Vec<u8>, EnvelopeHash>>>,
|
||||||
pub threads: Arc<RwLock<HashMap<MailboxHash, Threads>>>,
|
pub threads: Arc<RwLock<HashMap<MailboxHash, Threads>>>,
|
||||||
sent_mailbox: Arc<RwLock<Option<MailboxHash>>>,
|
pub sent_mailbox: Arc<RwLock<Option<MailboxHash>>>,
|
||||||
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
|
pub mailboxes: Arc<RwLock<HashMap<MailboxHash, HashSet<EnvelopeHash>>>>,
|
||||||
|
pub tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Collection {
|
impl Default for Collection {
|
||||||
|
@ -115,6 +116,7 @@ impl Collection {
|
||||||
|
|
||||||
Collection {
|
Collection {
|
||||||
envelopes: Arc::new(RwLock::new(Default::default())),
|
envelopes: Arc::new(RwLock::new(Default::default())),
|
||||||
|
tag_index: Arc::new(RwLock::new(BTreeMap::default())),
|
||||||
message_id_index,
|
message_id_index,
|
||||||
threads,
|
threads,
|
||||||
mailboxes,
|
mailboxes,
|
||||||
|
|
|
@ -44,7 +44,6 @@ pub use iterators::*;
|
||||||
use crate::text_processing::grapheme_clusters::*;
|
use crate::text_processing::grapheme_clusters::*;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -131,7 +130,7 @@ macro_rules! make {
|
||||||
e.parent = Some($p);
|
e.parent = Some($p);
|
||||||
});
|
});
|
||||||
let old_group = std::mem::replace($threads.groups.entry(old_group_hash).or_default(), ThreadGroup::Node {
|
let old_group = std::mem::replace($threads.groups.entry(old_group_hash).or_default(), ThreadGroup::Node {
|
||||||
parent: RefCell::new(parent_group_hash),
|
parent: Arc::new(RwLock::new(parent_group_hash)),
|
||||||
});
|
});
|
||||||
$threads.thread_nodes.entry($c).and_modify(|e| {
|
$threads.thread_nodes.entry($c).and_modify(|e| {
|
||||||
e.group = parent_group_hash;
|
e.group = parent_group_hash;
|
||||||
|
@ -292,7 +291,7 @@ pub struct Thread {
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub enum ThreadGroup {
|
pub enum ThreadGroup {
|
||||||
Root(Thread),
|
Root(Thread),
|
||||||
Node { parent: RefCell<ThreadHash> },
|
Node { parent: Arc<RwLock<ThreadHash>> },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ThreadGroup {
|
impl Default for ThreadGroup {
|
||||||
|
@ -411,16 +410,16 @@ impl ThreadNode {
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
pub struct Threads {
|
pub struct Threads {
|
||||||
pub thread_nodes: HashMap<ThreadNodeHash, ThreadNode>,
|
pub thread_nodes: HashMap<ThreadNodeHash, ThreadNode>,
|
||||||
root_set: RefCell<Vec<ThreadNodeHash>>,
|
root_set: Arc<RwLock<Vec<ThreadNodeHash>>>,
|
||||||
tree_index: RefCell<Vec<ThreadNodeHash>>,
|
tree_index: Arc<RwLock<Vec<ThreadNodeHash>>>,
|
||||||
pub groups: HashMap<ThreadHash, ThreadGroup>,
|
pub groups: HashMap<ThreadHash, ThreadGroup>,
|
||||||
|
|
||||||
message_ids: HashMap<Vec<u8>, ThreadNodeHash>,
|
message_ids: HashMap<Vec<u8>, ThreadNodeHash>,
|
||||||
pub message_ids_set: HashSet<Vec<u8>>,
|
pub message_ids_set: HashSet<Vec<u8>>,
|
||||||
pub missing_message_ids: HashSet<Vec<u8>>,
|
pub missing_message_ids: HashSet<Vec<u8>>,
|
||||||
pub hash_set: HashSet<EnvelopeHash>,
|
pub hash_set: HashSet<EnvelopeHash>,
|
||||||
sort: RefCell<(SortField, SortOrder)>,
|
sort: Arc<RwLock<(SortField, SortOrder)>>,
|
||||||
subsort: RefCell<(SortField, SortOrder)>,
|
subsort: Arc<RwLock<(SortField, SortOrder)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for ThreadNode {
|
impl PartialEq for ThreadNode {
|
||||||
|
@ -454,13 +453,13 @@ impl Threads {
|
||||||
pub fn find_group(&self, h: ThreadHash) -> ThreadHash {
|
pub fn find_group(&self, h: ThreadHash) -> ThreadHash {
|
||||||
let p = match self.groups[&h] {
|
let p = match self.groups[&h] {
|
||||||
ThreadGroup::Root(_) => return h,
|
ThreadGroup::Root(_) => return h,
|
||||||
ThreadGroup::Node { ref parent } => *parent.borrow(),
|
ThreadGroup::Node { ref parent } => *parent.read().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent_group = self.find_group(p);
|
let parent_group = self.find_group(p);
|
||||||
match self.groups[&h] {
|
match self.groups[&h] {
|
||||||
ThreadGroup::Node { ref parent } => {
|
ThreadGroup::Node { ref parent } => {
|
||||||
*parent.borrow_mut() = parent_group;
|
*parent.write().unwrap() = parent_group;
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -491,8 +490,8 @@ impl Threads {
|
||||||
message_ids_set,
|
message_ids_set,
|
||||||
missing_message_ids,
|
missing_message_ids,
|
||||||
hash_set,
|
hash_set,
|
||||||
sort: RefCell::new((SortField::Date, SortOrder::Desc)),
|
sort: Arc::new(RwLock::new((SortField::Date, SortOrder::Desc))),
|
||||||
subsort: RefCell::new((SortField::Subject, SortOrder::Desc)),
|
subsort: Arc::new(RwLock::new((SortField::Subject, SortOrder::Desc))),
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
@ -573,7 +572,7 @@ impl Threads {
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.thread_nodes[&t_id].parent.is_none() {
|
if self.thread_nodes[&t_id].parent.is_none() {
|
||||||
let mut tree_index = self.tree_index.borrow_mut();
|
let mut tree_index = self.tree_index.write().unwrap();
|
||||||
if let Some(i) = tree_index.iter().position(|t| *t == t_id) {
|
if let Some(i) = tree_index.iter().position(|t| *t == t_id) {
|
||||||
tree_index.remove(i);
|
tree_index.remove(i);
|
||||||
}
|
}
|
||||||
|
@ -845,7 +844,7 @@ impl Threads {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
save_graph(
|
save_graph(
|
||||||
&self.tree_index.borrow(),
|
&self.tree_index.read().unwrap(),
|
||||||
&self.thread_nodes,
|
&self.thread_nodes,
|
||||||
&self
|
&self
|
||||||
.message_ids
|
.message_ids
|
||||||
|
@ -871,7 +870,7 @@ impl Threads {
|
||||||
ref thread_nodes,
|
ref thread_nodes,
|
||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
let tree = &mut tree_index.borrow_mut();
|
let tree = &mut tree_index.write().unwrap();
|
||||||
for t in tree.iter_mut() {
|
for t in tree.iter_mut() {
|
||||||
thread_nodes[t].children.sort_by(|a, b| match subsort {
|
thread_nodes[t].children.sort_by(|a, b| match subsort {
|
||||||
(SortField::Date, SortOrder::Desc) => {
|
(SortField::Date, SortOrder::Desc) => {
|
||||||
|
@ -1090,7 +1089,7 @@ impl Threads {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fn inner_sort_by(&self, sort: (SortField, SortOrder), envelopes: &Envelopes) {
|
fn inner_sort_by(&self, sort: (SortField, SortOrder), envelopes: &Envelopes) {
|
||||||
let tree = &mut self.tree_index.borrow_mut();
|
let tree = &mut self.tree_index.write().unwrap();
|
||||||
let envelopes = envelopes.read().unwrap();
|
let envelopes = envelopes.read().unwrap();
|
||||||
tree.sort_by(|a, b| match sort {
|
tree.sort_by(|a, b| match sort {
|
||||||
(SortField::Date, SortOrder::Desc) => {
|
(SortField::Date, SortOrder::Desc) => {
|
||||||
|
@ -1172,13 +1171,13 @@ impl Threads {
|
||||||
subsort: (SortField, SortOrder),
|
subsort: (SortField, SortOrder),
|
||||||
envelopes: &Envelopes,
|
envelopes: &Envelopes,
|
||||||
) {
|
) {
|
||||||
if *self.sort.borrow() != sort {
|
if *self.sort.read().unwrap() != sort {
|
||||||
self.inner_sort_by(sort, envelopes);
|
self.inner_sort_by(sort, envelopes);
|
||||||
*self.sort.borrow_mut() = sort;
|
*self.sort.write().unwrap() = sort;
|
||||||
}
|
}
|
||||||
if *self.subsort.borrow() != subsort {
|
if *self.subsort.read().unwrap() != subsort {
|
||||||
self.inner_subsort_by(subsort, envelopes);
|
self.inner_subsort_by(subsort, envelopes);
|
||||||
*self.subsort.borrow_mut() = subsort;
|
*self.subsort.write().unwrap() = subsort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,11 +1195,11 @@ impl Threads {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_len(&self) -> usize {
|
pub fn root_len(&self) -> usize {
|
||||||
self.tree_index.borrow().len()
|
self.tree_index.read().unwrap().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_set(&self, idx: usize) -> ThreadNodeHash {
|
pub fn root_set(&self, idx: usize) -> ThreadNodeHash {
|
||||||
self.tree_index.borrow()[idx]
|
self.tree_index.read().unwrap()[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roots(&self) -> SmallVec<[ThreadHash; 1024]> {
|
pub fn roots(&self) -> SmallVec<[ThreadHash; 1024]> {
|
||||||
|
|
|
@ -895,9 +895,9 @@ impl CompactListing {
|
||||||
let thread = threads.thread_ref(hash);
|
let thread = threads.thread_ref(hash);
|
||||||
let mut tags = String::new();
|
let mut tags = String::new();
|
||||||
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
|
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
|
||||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
let account = &context.accounts[&self.cursor_pos.0];
|
||||||
if let Some(t) = backend_lck.tags() {
|
if account.backend_capabilities.supports_tags {
|
||||||
let tags_lck = t.read().unwrap();
|
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||||
for t in e.labels().iter() {
|
for t in e.labels().iter() {
|
||||||
if mailbox_settings!(
|
if mailbox_settings!(
|
||||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||||
|
|
|
@ -908,9 +908,9 @@ impl ConversationsListing {
|
||||||
let thread = threads.thread_ref(hash);
|
let thread = threads.thread_ref(hash);
|
||||||
let mut tags = String::new();
|
let mut tags = String::new();
|
||||||
let mut colors = SmallVec::new();
|
let mut colors = SmallVec::new();
|
||||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
let account = &context.accounts[&self.cursor_pos.0];
|
||||||
if let Some(t) = backend_lck.tags() {
|
if account.backend_capabilities.supports_tags {
|
||||||
let tags_lck = t.read().unwrap();
|
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||||
for t in e.labels().iter() {
|
for t in e.labels().iter() {
|
||||||
if mailbox_settings!(
|
if mailbox_settings!(
|
||||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||||
|
|
|
@ -732,9 +732,9 @@ impl PlainListing {
|
||||||
fn make_entry_string(&self, e: EnvelopeRef, context: &Context) -> EntryStrings {
|
fn make_entry_string(&self, e: EnvelopeRef, context: &Context) -> EntryStrings {
|
||||||
let mut tags = String::new();
|
let mut tags = String::new();
|
||||||
let mut colors = SmallVec::new();
|
let mut colors = SmallVec::new();
|
||||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
let account = &context.accounts[&self.cursor_pos.0];
|
||||||
if let Some(t) = backend_lck.tags() {
|
if account.backend_capabilities.supports_tags {
|
||||||
let tags_lck = t.read().unwrap();
|
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||||
for t in e.labels().iter() {
|
for t in e.labels().iter() {
|
||||||
if mailbox_settings!(
|
if mailbox_settings!(
|
||||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||||
|
|
|
@ -839,9 +839,9 @@ impl ThreadListing {
|
||||||
fn make_entry_string(&self, e: &Envelope, context: &Context) -> EntryStrings {
|
fn make_entry_string(&self, e: &Envelope, context: &Context) -> EntryStrings {
|
||||||
let mut tags = String::new();
|
let mut tags = String::new();
|
||||||
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
|
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
|
||||||
let backend_lck = context.accounts[&self.cursor_pos.0].backend.read().unwrap();
|
let account = &context.accounts[&self.cursor_pos.0];
|
||||||
if let Some(t) = backend_lck.tags() {
|
if account.backend_capabilities.supports_tags {
|
||||||
let tags_lck = t.read().unwrap();
|
let tags_lck = account.collection.tag_index.read().unwrap();
|
||||||
for t in e.labels().iter() {
|
for t in e.labels().iter() {
|
||||||
if mailbox_settings!(
|
if mailbox_settings!(
|
||||||
context[self.cursor_pos.0][&self.cursor_pos.1]
|
context[self.cursor_pos.0][&self.cursor_pos.1]
|
||||||
|
|
|
@ -517,7 +517,7 @@ impl Account {
|
||||||
tree: Default::default(),
|
tree: Default::default(),
|
||||||
address_book,
|
address_book,
|
||||||
sent_mailbox: Default::default(),
|
sent_mailbox: Default::default(),
|
||||||
collection: Default::default(),
|
collection: backend.collection(),
|
||||||
settings,
|
settings,
|
||||||
sender,
|
sender,
|
||||||
job_executor,
|
job_executor,
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub struct PluginBackend {
|
||||||
plugin: Plugin,
|
plugin: Plugin,
|
||||||
child: std::process::Child,
|
child: std::process::Child,
|
||||||
channel: Arc<Mutex<RpcChannel>>,
|
channel: Arc<Mutex<RpcChannel>>,
|
||||||
tag_index: Option<Arc<RwLock<BTreeMap<u64, String>>>>,
|
collection: melib::Collection,
|
||||||
is_online: Arc<Mutex<(std::time::Instant, Result<()>)>>,
|
is_online: Arc<Mutex<(std::time::Instant, Result<()>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,6 @@ impl MailBackend for PluginBackend {
|
||||||
Ok(Box::new(PluginOp {
|
Ok(Box::new(PluginOp {
|
||||||
hash,
|
hash,
|
||||||
channel: self.channel.clone(),
|
channel: self.channel.clone(),
|
||||||
tag_index: self.tag_index.clone(),
|
|
||||||
bytes: None,
|
bytes: None,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -219,8 +218,8 @@ impl MailBackend for PluginBackend {
|
||||||
) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
|
) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
|
||||||
Err(MeliError::new("Unimplemented."))
|
Err(MeliError::new("Unimplemented."))
|
||||||
}
|
}
|
||||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
fn collection(&self) -> melib::Collection {
|
||||||
self.tag_index.clone()
|
self.collection.clone()
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn ::std::any::Any {
|
fn as_any(&self) -> &dyn ::std::any::Any {
|
||||||
self
|
self
|
||||||
|
@ -257,7 +256,7 @@ impl PluginBackend {
|
||||||
child,
|
child,
|
||||||
plugin,
|
plugin,
|
||||||
channel: Arc::new(Mutex::new(channel)),
|
channel: Arc::new(Mutex::new(channel)),
|
||||||
tag_index: None,
|
collection: Default::default(),
|
||||||
is_online: Arc::new(Mutex::new((now, Err(MeliError::new("Unitialized"))))),
|
is_online: Arc::new(Mutex::new((now, Err(MeliError::new("Unitialized"))))),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -285,7 +284,6 @@ impl PluginBackend {
|
||||||
struct PluginOp {
|
struct PluginOp {
|
||||||
hash: EnvelopeHash,
|
hash: EnvelopeHash,
|
||||||
channel: Arc<Mutex<RpcChannel>>,
|
channel: Arc<Mutex<RpcChannel>>,
|
||||||
tag_index: Option<Arc<RwLock<BTreeMap<u64, String>>>>,
|
|
||||||
bytes: Option<String>,
|
bytes: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue