melib: remove argument from MailBackend operation()
The operation() method on the MailBackend trait returns a trait object that can read or modify an Envelope directly from the backend. This is used to get eg the envelope's text, or set flags. It has two arguments, envelope hash and folder hash. Only the Maildir backend needed the latter argument, and it can be replaced with a dictionary to match envelope hashes to folder hashes within the Maildir backend.sql
parent
0a606a71d1
commit
d926cadc4d
|
@ -176,7 +176,7 @@ pub enum FolderOperation {
|
||||||
|
|
||||||
type NewFolderName = String;
|
type NewFolderName = String;
|
||||||
|
|
||||||
pub trait MailBackend: ::std::fmt::Debug {
|
pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
|
||||||
fn is_online(&self) -> bool;
|
fn is_online(&self) -> bool;
|
||||||
fn get(&mut self, folder: &Folder) -> Async<Result<Vec<Envelope>>>;
|
fn get(&mut self, folder: &Folder) -> Async<Result<Vec<Envelope>>>;
|
||||||
fn watch(
|
fn watch(
|
||||||
|
@ -185,7 +185,7 @@ pub trait MailBackend: ::std::fmt::Debug {
|
||||||
work_context: WorkContext,
|
work_context: WorkContext,
|
||||||
) -> Result<std::thread::ThreadId>;
|
) -> Result<std::thread::ThreadId>;
|
||||||
fn folders(&self) -> FnvHashMap<FolderHash, Folder>;
|
fn folders(&self) -> FnvHashMap<FolderHash, Folder>;
|
||||||
fn operation(&self, hash: EnvelopeHash, folder_hash: FolderHash) -> Box<dyn BackendOp>;
|
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp>;
|
||||||
|
|
||||||
fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> Result<()>;
|
fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> Result<()>;
|
||||||
fn folder_operation(&mut self, _path: &str, _op: FolderOperation) -> Result<()> {
|
fn folder_operation(&mut self, _path: &str, _op: FolderOperation) -> Result<()> {
|
||||||
|
|
|
@ -259,7 +259,7 @@ impl MailBackend for ImapType {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operation(&self, hash: EnvelopeHash, _folder_hash: FolderHash) -> Box<dyn BackendOp> {
|
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
|
||||||
let (uid, folder_hash) = self.hash_index.lock().unwrap()[&hash];
|
let (uid, folder_hash) = self.hash_index.lock().unwrap()[&hash];
|
||||||
Box::new(ImapOp::new(
|
Box::new(ImapOp::new(
|
||||||
uid,
|
uid,
|
||||||
|
|
|
@ -114,7 +114,7 @@ pub type HashIndexes = Arc<Mutex<FnvHashMap<FolderHash, HashIndex>>>;
|
||||||
pub struct MaildirType {
|
pub struct MaildirType {
|
||||||
name: String,
|
name: String,
|
||||||
folders: FnvHashMap<FolderHash, MaildirFolder>,
|
folders: FnvHashMap<FolderHash, MaildirFolder>,
|
||||||
//folder_index: FnvHashMap<FolderHash, usize>,
|
folder_index: Arc<Mutex<FnvHashMap<EnvelopeHash, FolderHash>>>,
|
||||||
hash_indexes: HashIndexes,
|
hash_indexes: HashIndexes,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
@ -207,6 +207,7 @@ impl MailBackend for MaildirType {
|
||||||
let cache_dir = xdg::BaseDirectories::with_profile("meli", &self.name).unwrap();
|
let cache_dir = xdg::BaseDirectories::with_profile("meli", &self.name).unwrap();
|
||||||
debug!("watching {:?}", root_path);
|
debug!("watching {:?}", root_path);
|
||||||
let hash_indexes = self.hash_indexes.clone();
|
let hash_indexes = self.hash_indexes.clone();
|
||||||
|
let folder_index = self.folder_index.clone();
|
||||||
let handle = thread::Builder::new()
|
let handle = thread::Builder::new()
|
||||||
.name("folder watch".to_string())
|
.name("folder watch".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
|
@ -255,6 +256,7 @@ impl MailBackend for MaildirType {
|
||||||
&cache_dir,
|
&cache_dir,
|
||||||
file_name,
|
file_name,
|
||||||
) {
|
) {
|
||||||
|
folder_index.lock().unwrap().insert(env.hash(),folder_hash);
|
||||||
debug!(
|
debug!(
|
||||||
"Create event {} {} {}",
|
"Create event {} {} {}",
|
||||||
env.hash(),
|
env.hash(),
|
||||||
|
@ -300,6 +302,7 @@ impl MailBackend for MaildirType {
|
||||||
&cache_dir,
|
&cache_dir,
|
||||||
file_name,
|
file_name,
|
||||||
) {
|
) {
|
||||||
|
folder_index.lock().unwrap().insert(env.hash(),folder_hash);
|
||||||
sender.send(RefreshEvent {
|
sender.send(RefreshEvent {
|
||||||
hash: folder_hash,
|
hash: folder_hash,
|
||||||
kind: Create(Box::new(env)),
|
kind: Create(Box::new(env)),
|
||||||
|
@ -398,6 +401,7 @@ impl MailBackend for MaildirType {
|
||||||
hash: get_path_hash!(dest),
|
hash: get_path_hash!(dest),
|
||||||
kind: Rename(old_hash, new_hash),
|
kind: Rename(old_hash, new_hash),
|
||||||
});
|
});
|
||||||
|
folder_index.lock().unwrap().insert(new_hash,get_path_hash!(dest) );
|
||||||
index_lock.insert(new_hash, dest.into());
|
index_lock.insert(new_hash, dest.into());
|
||||||
continue;
|
continue;
|
||||||
} else if !index_lock.contains_key(&new_hash)
|
} else if !index_lock.contains_key(&new_hash)
|
||||||
|
@ -434,6 +438,7 @@ impl MailBackend for MaildirType {
|
||||||
&cache_dir,
|
&cache_dir,
|
||||||
file_name,
|
file_name,
|
||||||
) {
|
) {
|
||||||
|
folder_index.lock().unwrap().insert(env.hash(),folder_hash);
|
||||||
debug!(
|
debug!(
|
||||||
"Create event {} {} {}",
|
"Create event {} {} {}",
|
||||||
env.hash(),
|
env.hash(),
|
||||||
|
@ -477,8 +482,12 @@ impl MailBackend for MaildirType {
|
||||||
Ok(handle.thread().id())
|
Ok(handle.thread().id())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operation(&self, hash: EnvelopeHash, folder_hash: FolderHash) -> Box<dyn BackendOp> {
|
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
|
||||||
Box::new(MaildirOp::new(hash, self.hash_indexes.clone(), folder_hash))
|
Box::new(MaildirOp::new(
|
||||||
|
hash,
|
||||||
|
self.hash_indexes.clone(),
|
||||||
|
self.folder_index.lock().unwrap()[&hash],
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> Result<()> {
|
fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> Result<()> {
|
||||||
|
@ -663,6 +672,7 @@ impl MaildirType {
|
||||||
name: settings.name().to_string(),
|
name: settings.name().to_string(),
|
||||||
folders,
|
folders,
|
||||||
hash_indexes,
|
hash_indexes,
|
||||||
|
folder_index: Default::default(),
|
||||||
path: root_path,
|
path: root_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -689,6 +699,7 @@ impl MaildirType {
|
||||||
let name = format!("parsing {:?}", folder.name());
|
let name = format!("parsing {:?}", folder.name());
|
||||||
let root_path = self.path.to_path_buf();
|
let root_path = self.path.to_path_buf();
|
||||||
let map = self.hash_indexes.clone();
|
let map = self.hash_indexes.clone();
|
||||||
|
let folder_index = self.folder_index.clone();
|
||||||
|
|
||||||
let closure = move |work_context: crate::async_workers::WorkContext| {
|
let closure = move |work_context: crate::async_workers::WorkContext| {
|
||||||
let name = name.clone();
|
let name = name.clone();
|
||||||
|
@ -698,6 +709,7 @@ impl MaildirType {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let root_path = root_path.clone();
|
let root_path = root_path.clone();
|
||||||
let map = map.clone();
|
let map = map.clone();
|
||||||
|
let folder_index = folder_index.clone();
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let cache_dir = cache_dir.clone();
|
let cache_dir = cache_dir.clone();
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
|
@ -737,6 +749,7 @@ impl MaildirType {
|
||||||
let cache_dir = cache_dir.clone();
|
let cache_dir = cache_dir.clone();
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let map = map.clone();
|
let map = map.clone();
|
||||||
|
let folder_index = folder_index.clone();
|
||||||
let root_path = root_path.clone();
|
let root_path = root_path.clone();
|
||||||
let s = scope.builder().name(name.clone()).spawn(move |_| {
|
let s = scope.builder().name(name.clone()).spawn(move |_| {
|
||||||
let len = chunk.len();
|
let len = chunk.len();
|
||||||
|
@ -746,6 +759,7 @@ impl MaildirType {
|
||||||
for c in chunk.chunks(size) {
|
for c in chunk.chunks(size) {
|
||||||
//thread::yield_now();
|
//thread::yield_now();
|
||||||
let map = map.clone();
|
let map = map.clone();
|
||||||
|
let folder_index = folder_index.clone();
|
||||||
let len = c.len();
|
let len = c.len();
|
||||||
for file in c {
|
for file in c {
|
||||||
/* Check if we have a cache file with this email's
|
/* Check if we have a cache file with this email's
|
||||||
|
@ -768,6 +782,10 @@ impl MaildirType {
|
||||||
let map = map.entry(folder_hash).or_default();
|
let map = map.entry(folder_hash).or_default();
|
||||||
let hash = env.hash();
|
let hash = env.hash();
|
||||||
map.insert(hash, file.clone().into());
|
map.insert(hash, file.clone().into());
|
||||||
|
folder_index
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(hash, folder_hash);
|
||||||
local_r.push(env);
|
local_r.push(env);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -784,6 +802,10 @@ impl MaildirType {
|
||||||
folder_hash,
|
folder_hash,
|
||||||
));
|
));
|
||||||
if let Some(e) = Envelope::from_token(op, hash) {
|
if let Some(e) = Envelope::from_token(op, hash) {
|
||||||
|
folder_index
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(e.hash(), folder_hash);
|
||||||
if let Ok(cached) =
|
if let Ok(cached) =
|
||||||
cache_dir.place_cache_file(file_name)
|
cache_dir.place_cache_file(file_name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -537,7 +537,7 @@ impl MailBackend for MboxType {
|
||||||
.map(|(h, f)| (*h, f.clone() as Folder))
|
.map(|(h, f)| (*h, f.clone() as Folder))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
fn operation(&self, hash: EnvelopeHash, _folder_hash: FolderHash) -> Box<dyn BackendOp> {
|
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
|
||||||
let (offset, length) = {
|
let (offset, length) = {
|
||||||
let index = self.index.lock().unwrap();
|
let index = self.index.lock().unwrap();
|
||||||
index[&hash]
|
index[&hash]
|
||||||
|
|
|
@ -740,25 +740,12 @@ impl Account {
|
||||||
self.collection.contains_key(&h)
|
self.collection.contains_key(&h)
|
||||||
}
|
}
|
||||||
pub fn operation(&self, h: EnvelopeHash) -> Box<dyn BackendOp> {
|
pub fn operation(&self, h: EnvelopeHash) -> Box<dyn BackendOp> {
|
||||||
for mailbox in self.folders.values() {
|
let operation = self.backend.operation(h);
|
||||||
match mailbox {
|
if self.settings.account.read_only() {
|
||||||
MailboxEntry::Available(ref m) | MailboxEntry::Parsing(ref m, _, _) => {
|
ReadOnlyOp::new(operation)
|
||||||
if m.envelopes.contains(&h) {
|
} else {
|
||||||
let operation = self.backend.operation(h, m.folder.hash());
|
operation
|
||||||
if self.settings.account.read_only() {
|
|
||||||
return ReadOnlyOp::new(operation);
|
|
||||||
} else {
|
|
||||||
return operation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
debug!("didn't find {}", h);
|
|
||||||
debug!(&self.folders);
|
|
||||||
//debug!(&self.collection.envelopes);
|
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thread(&self, h: ThreadHash, f: FolderHash) -> &ThreadNode {
|
pub fn thread(&self, h: ThreadHash, f: FolderHash) -> &ThreadNode {
|
||||||
|
|
Loading…
Reference in New Issue