diff --git a/melib/src/async_workers.rs b/melib/src/async_workers.rs
deleted file mode 100644
index 7b45c09f..00000000
--- a/melib/src/async_workers.rs
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * meli - async 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 .
- */
-
-/*!
- * Primitive Async/Wait implementation.
- *
- * To create an Async promise, create an AsyncBuilder. Ask for its channel receiver/sender with
- * `tx` and `rx` methods to pass them in your worker's closure. Build an `Async` with your
- * `JoinHandle`. The thread must communicate with the `Async` object via `AsyncStatus`
- * messages.
- *
- * When `Async` receives `AsyncStatus::Finished` it joins the thread and takes its value which
- * can be extracted with `extract`.
- */
-
-use crossbeam::{
- bounded,
- channel::{Receiver, Sender},
- select,
-};
-use std::fmt;
-
-#[derive(Clone, Debug)]
-pub struct WorkContext {
- pub new_work: Sender,
- pub set_name: Sender<(std::thread::ThreadId, String)>,
- pub set_status: Sender<(std::thread::ThreadId, String)>,
- pub finished: Sender,
-}
-
-pub struct Work {
- priority: u64,
- pub is_static: bool,
- pub closure: Box () + Send + Sync>,
-}
-
-impl Ord for Work {
- fn cmp(&self, other: &Work) -> std::cmp::Ordering {
- self.priority.cmp(&other.priority)
- }
-}
-
-impl PartialOrd for Work {
- fn partial_cmp(&self, other: &Work) -> Option {
- Some(self.priority.cmp(&other.priority))
- }
-}
-
-impl PartialEq for Work {
- fn eq(&self, other: &Work) -> bool {
- self.priority == other.priority
- }
-}
-
-impl Eq for Work {}
-
-impl Work {
- pub fn compute(self, work_context: WorkContext) {
- (self.closure)(work_context);
- }
-}
-
-impl fmt::Debug for Work {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Work object")
- }
-}
-
-/// Messages to pass between `Async` owner and its worker thread.
-#[derive(Clone)]
-pub enum AsyncStatus {
- NoUpdate,
- Payload(T),
- Finished,
- ///The number may hold whatever meaning the user chooses.
- ProgressReport(usize),
-}
-
-impl fmt::Debug for AsyncStatus {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- AsyncStatus::NoUpdate => write!(f, "AsyncStatus::NoUpdate"),
- AsyncStatus::Payload(_) => write!(f, "AsyncStatus::Payload(_)"),
- AsyncStatus::Finished => write!(f, "AsyncStatus::Finished"),
- AsyncStatus::ProgressReport(u) => write!(f, "AsyncStatus::ProgressReport({})", u),
- }
- }
-}
-
-/// A builder object for `Async`
-#[derive(Debug, Clone)]
-pub struct AsyncBuilder {
- tx: Sender>,
- rx: Receiver>,
- priority: u64,
- is_static: bool,
-}
-
-#[derive(Debug)]
-pub struct Async {
- work: Option,
- active: bool,
- tx: Sender>,
- rx: Receiver>,
-}
-
-impl Default for AsyncBuilder {
- fn default() -> Self {
- AsyncBuilder::::new()
- }
-}
-
-impl AsyncBuilder
-where
- T: Send + Sync,
-{
- pub fn new() -> Self {
- let (sender, receiver) = bounded(8 * ::std::mem::size_of::>());
- AsyncBuilder {
- tx: sender,
- rx: receiver,
- priority: 0,
- is_static: false,
- }
- }
- /// Returns the sender object of the promise's channel.
- pub fn tx(&mut self) -> Sender> {
- self.tx.clone()
- }
- /// Returns the receiver object of the promise's channel.
- pub fn rx(&mut self) -> Receiver> {
- self.rx.clone()
- }
-
- pub fn set_priority(&mut self, new_val: u64) -> &mut Self {
- self.priority = new_val;
- self
- }
-
- pub fn set_is_static(&mut self, new_val: bool) -> &mut Self {
- self.is_static = new_val;
- self
- }
-
- /// Returns an `Async` object that contains a `Thread` join handle that returns a `T`
- pub fn build(self, work: Box () + Send + Sync>) -> Async {
- Async {
- work: Some(Work {
- priority: self.priority,
- is_static: self.is_static,
- closure: work,
- }),
- tx: self.tx,
- rx: self.rx,
- active: false,
- }
- }
-}
-
-impl Async
-where
- T: Send + Sync,
-{
- pub fn work(&mut self) -> Option {
- if !self.active {
- self.active = true;
- self.work.take()
- } else {
- None
- }
- }
- /// Returns the sender object of the promise's channel.
- pub fn tx(&mut self) -> Sender> {
- self.tx.clone()
- }
- /// Returns the receiver object of the promise's channel.
- pub fn rx(&mut self) -> Receiver> {
- self.rx.clone()
- }
- /// Polls worker thread and returns result.
- pub fn poll_block(&mut self) -> Result, ()> {
- if !self.active {
- return Ok(AsyncStatus::Finished);
- }
-
- let rx = &self.rx;
- select! {
- recv(rx) -> r => {
- match r {
- Ok(p @ AsyncStatus::Payload(_)) => {
- Ok(p)
- },
- Ok(f @ AsyncStatus::Finished) => {
- self.active = false;
- Ok(f)
- },
- Ok(a) => {
- Ok(a)
- }
- Err(_) => {
- Err(())
- },
- }
- },
- }
- }
- /// Polls worker thread and returns result.
- pub fn poll(&mut self) -> Result, ()> {
- if !self.active {
- return Ok(AsyncStatus::Finished);
- }
-
- let rx = &self.rx;
- select! {
- default => {
- Ok(AsyncStatus::NoUpdate)
- },
- recv(rx) -> r => {
- match r {
- Ok(p @ AsyncStatus::Payload(_)) => {
- Ok(p)
- },
- Ok(f @ AsyncStatus::Finished) => {
- self.active = false;
- Ok(f)
- },
- Ok(a) => {
- Ok(a)
- }
- Err(_) => {
- Err(())
- },
- }
- },
- }
- }
-}
diff --git a/melib/src/backends.rs b/melib/src/backends.rs
index e6954ec0..62434bc5 100644
--- a/melib/src/backends.rs
+++ b/melib/src/backends.rs
@@ -49,7 +49,6 @@ pub mod mbox;
pub use self::imap::ImapType;
#[cfg(feature = "imap_backend")]
pub use self::nntp::NntpType;
-use crate::async_workers::*;
use crate::conf::AccountSettings;
use crate::error::{MeliError, Result};
@@ -304,31 +303,23 @@ pub type ResultFuture = Result> + Send
pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
fn capabilities(&self) -> MailBackendCapabilities;
- fn is_online(&self) -> Result<()> {
+ fn is_online(&self) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
- fn is_online_async(&self) -> ResultFuture<()> {
- Err(MeliError::new("Unimplemented."))
- }
- fn fetch(&mut self, mailbox_hash: MailboxHash) -> Result>>>;
- fn fetch_async(
+ //fn fetch(&mut self, mailbox_hash: MailboxHash) -> Result>>>;
+ fn fetch(
&mut self,
_mailbox_hash: MailboxHash,
) -> Result>> + Send + 'static>>> {
Err(MeliError::new("Unimplemented."))
}
- fn refresh(&mut self, _mailbox_hash: MailboxHash) -> Result> {
+ fn refresh(&mut self, _mailbox_hash: MailboxHash) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
- fn refresh_async(&mut self, _mailbox_hash: MailboxHash) -> ResultFuture<()> {
+ fn watch(&self) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
- fn watch(&self, work_context: WorkContext) -> Result;
- fn watch_async(&self) -> ResultFuture<()> {
- Err(MeliError::new("Unimplemented."))
- }
- fn mailboxes(&self) -> Result>;
- fn mailboxes_async(&self) -> ResultFuture> {
+ fn mailboxes(&self) -> ResultFuture> {
Err(MeliError::new("Unimplemented."))
}
fn operation(&self, hash: EnvelopeHash) -> Result>;
diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs
index a383b6a0..106c1bd5 100644
--- a/melib/src/backends/imap.rs
+++ b/melib/src/backends/imap.rs
@@ -36,11 +36,11 @@ mod cache;
pub mod managesieve;
mod untagged;
-use crate::async_workers::{Async, WorkContext};
use crate::backends::{
RefreshEventKind::{self, *},
*,
};
+
use crate::conf::AccountSettings;
use crate::connections::timeout;
use crate::email::*;
@@ -260,7 +260,7 @@ impl MailBackend for ImapType {
}
}
- fn fetch_async(
+ fn fetch(
&mut self,
mailbox_hash: MailboxHash,
) -> Result>> + Send + 'static>>> {
@@ -289,7 +289,7 @@ impl MailBackend for ImapType {
}))
}
- fn refresh_async(&mut self, mailbox_hash: MailboxHash) -> ResultFuture<()> {
+ fn refresh(&mut self, mailbox_hash: MailboxHash) -> ResultFuture<()> {
let main_conn = self.connection.clone();
let uid_store = self.uid_store.clone();
Ok(Box::pin(async move {
@@ -304,7 +304,7 @@ impl MailBackend for ImapType {
}))
}
- fn mailboxes_async(&self) -> ResultFuture> {
+ fn mailboxes(&self) -> ResultFuture> {
let uid_store = self.uid_store.clone();
let connection = self.connection.clone();
Ok(Box::pin(async move {
@@ -356,12 +356,12 @@ impl MailBackend for ImapType {
}))
}
- fn is_online_async(&self) -> ResultFuture<()> {
+ fn is_online(&self) -> ResultFuture<()> {
let connection = self.connection.clone();
Ok(Box::pin(async move {
match timeout(std::time::Duration::from_secs(3), connection.lock()).await {
Ok(mut conn) => {
- debug!("is_online_async");
+ debug!("is_online");
match debug!(timeout(std::time::Duration::from_secs(3), conn.connect()).await) {
Ok(Ok(())) => Ok(()),
Err(err) | Ok(Err(err)) => {
@@ -375,20 +375,7 @@ impl MailBackend for ImapType {
}))
}
- fn fetch(&mut self, _mailbox_hash: MailboxHash) -> Result>>> {
- Err(MeliError::new("Unimplemented."))
- }
-
- fn refresh(&mut self, _mailbox_hash: MailboxHash) -> Result> {
- Err(MeliError::new("Unimplemented."))
- }
-
- fn watch(&self, _work_context: WorkContext) -> Result {
- Err(MeliError::new("Unimplemented."))
- }
-
- fn watch_async(&self) -> ResultFuture<()> {
- debug!("watch_async called");
+ fn watch(&self) -> ResultFuture<()> {
let conn = ImapConnection::new_connection(&self.server_conf, self.uid_store.clone());
let main_conn = self.connection.clone();
let uid_store = self.uid_store.clone();
@@ -417,15 +404,11 @@ impl MailBackend for ImapType {
} else {
poll_with_examine(kit).await?;
}
- debug!("watch_async future returning");
+ debug!("watch future returning");
Ok(())
}))
}
- fn mailboxes(&self) -> Result> {
- Err(MeliError::new("Unimplemented."))
- }
-
fn operation(&self, hash: EnvelopeHash) -> Result> {
let (uid, mailbox_hash) = if let Some(v) =
self.uid_store.hash_index.lock().unwrap().get(&hash)
@@ -748,7 +731,7 @@ impl MailBackend for ImapType {
) -> ResultFuture<(MailboxHash, HashMap)> {
let uid_store = self.uid_store.clone();
let connection = self.connection.clone();
- let new_mailbox_fut = self.mailboxes_async();
+ let new_mailbox_fut = self.mailboxes();
Ok(Box::pin(async move {
/* Must transform path to something the IMAP server will accept
*
@@ -819,7 +802,7 @@ impl MailBackend for ImapType {
) -> ResultFuture> {
let uid_store = self.uid_store.clone();
let connection = self.connection.clone();
- let new_mailbox_fut = self.mailboxes_async();
+ let new_mailbox_fut = self.mailboxes();
Ok(Box::pin(async move {
let imap_path: String;
let no_select: bool;
@@ -923,7 +906,7 @@ impl MailBackend for ImapType {
) -> ResultFuture {
let uid_store = self.uid_store.clone();
let connection = self.connection.clone();
- let new_mailbox_fut = self.mailboxes_async();
+ let new_mailbox_fut = self.mailboxes();
Ok(Box::pin(async move {
let command: String;
let mut response = String::with_capacity(8 * 1024);
diff --git a/melib/src/backends/jmap.rs b/melib/src/backends/jmap.rs
index 8c07f442..feb90b9b 100644
--- a/melib/src/backends/jmap.rs
+++ b/melib/src/backends/jmap.rs
@@ -19,7 +19,6 @@
* along with meli. If not, see .
*/
-use crate::async_workers::{Async, WorkContext};
use crate::backends::*;
use crate::conf::AccountSettings;
use crate::email::*;
@@ -207,7 +206,7 @@ impl MailBackend for JmapType {
CAPABILITIES
}
- fn is_online_async(&self) -> ResultFuture<()> {
+ fn is_online(&self) -> ResultFuture<()> {
let online = self.online.clone();
Ok(Box::pin(async move {
//match timeout(std::time::Duration::from_secs(3), connection.lock()).await {
@@ -221,7 +220,7 @@ impl MailBackend for JmapType {
}))
}
- fn fetch_async(
+ fn fetch(
&mut self,
mailbox_hash: MailboxHash,
) -> Result>> + Send + 'static>>> {
@@ -243,13 +242,13 @@ impl MailBackend for JmapType {
}))
}
- fn watch_async(&self) -> ResultFuture<()> {
+ fn watch(&self) -> ResultFuture<()> {
Ok(Box::pin(async move {
Err(MeliError::from("JMAP watch for updates is unimplemented"))
}))
}
- fn mailboxes_async(&self) -> ResultFuture> {
+ fn mailboxes(&self) -> ResultFuture> {
let mailboxes = self.mailboxes.clone();
let connection = self.connection.clone();
Ok(Box::pin(async move {
@@ -354,18 +353,6 @@ impl MailBackend for JmapType {
}))
}
- fn fetch(&mut self, _mailbox_hash: MailboxHash) -> Result>>> {
- Err(MeliError::new("Unimplemented."))
- }
-
- fn watch(&self, _work_context: WorkContext) -> Result {
- Err(MeliError::new("Unimplemented."))
- }
-
- fn mailboxes(&self) -> Result> {
- Err(MeliError::new("Unimplemented."))
- }
-
fn rename_mailbox(
&mut self,
_mailbox_hash: MailboxHash,
diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs
index f159ce2f..44739fc5 100644
--- a/melib/src/backends/maildir/backend.rs
+++ b/melib/src/backends/maildir/backend.rs
@@ -20,7 +20,6 @@
*/
use super::{MaildirMailbox, MaildirOp, MaildirPathTrait};
-use crate::async_workers::*;
use crate::backends::{RefreshEventKind::*, *};
use crate::conf::AccountSettings;
use crate::email::{Envelope, EnvelopeHash, Flag};
@@ -40,10 +39,8 @@ use std::io::{self, Read, Write};
use std::ops::{Deref, DerefMut};
use std::os::unix::fs::PermissionsExt;
use std::path::{Component, Path, PathBuf};
-use std::result;
use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};
-use std::thread;
#[derive(Clone, Debug, PartialEq)]
pub(super) enum PathMod {
@@ -188,31 +185,20 @@ impl MailBackend for MaildirType {
CAPABILITIES
}
- fn is_online(&self) -> Result<()> {
- Ok(())
- }
-
- fn is_online_async(&self) -> ResultFuture<()> {
+ fn is_online(&self) -> ResultFuture<()> {
Ok(Box::pin(async { Ok(()) }))
}
- fn mailboxes(&self) -> Result> {
- Ok(self
+ fn mailboxes(&self) -> ResultFuture> {
+ let res = Ok(self
.mailboxes
.iter()
.map(|(h, f)| (*h, BackendMailbox::clone(f)))
- .collect())
- }
- fn mailboxes_async(&self) -> ResultFuture> {
- let res = self.mailboxes();
+ .collect());
Ok(Box::pin(async { res }))
}
- fn fetch(&mut self, mailbox_hash: MailboxHash) -> Result>>> {
- Ok(self.multicore(4, mailbox_hash))
- }
-
- fn fetch_async(
+ fn fetch(
&mut self,
mailbox_hash: MailboxHash,
) -> Result>> + Send + 'static>>>
@@ -224,14 +210,19 @@ impl MailBackend for MaildirType {
let root_path = self.path.to_path_buf();
let map = self.hash_indexes.clone();
let mailbox_index = self.mailbox_index.clone();
- super::stream::MaildirStream::new(&self.name, mailbox_hash, unseen, total, path, root_path, map, mailbox_index)
+ super::stream::MaildirStream::new(
+ &self.name,
+ mailbox_hash,
+ unseen,
+ total,
+ path,
+ root_path,
+ map,
+ mailbox_index,
+ )
}
- fn refresh(
- &mut self,
- mailbox_hash: MailboxHash,
- ) -> Result> {
- let w = AsyncBuilder::new();
+ fn refresh(&mut self, mailbox_hash: MailboxHash) -> ResultFuture<()> {
let cache_dir = xdg::BaseDirectories::with_profile("meli", &self.name).unwrap();
let account_hash = {
let mut hasher = DefaultHasher::default();
@@ -240,117 +231,116 @@ impl MailBackend for MaildirType {
};
let sender = self.event_consumer.clone();
- let handle = {
- let mailbox: &MaildirMailbox = &self.mailboxes[&mailbox_hash];
- let path: PathBuf = mailbox.fs_path().into();
- let name = format!("refresh {:?}", mailbox.name());
- let root_path = self.path.to_path_buf();
- let map = self.hash_indexes.clone();
- let mailbox_index = self.mailbox_index.clone();
+ let mailbox: &MaildirMailbox = &self.mailboxes[&mailbox_hash];
+ let path: PathBuf = mailbox.fs_path().into();
+ let root_path = self.path.to_path_buf();
+ let map = self.hash_indexes.clone();
+ let mailbox_index = self.mailbox_index.clone();
- Box::new(move |work_context: crate::async_workers::WorkContext| {
- work_context
- .set_name
- .send((std::thread::current().id(), name.clone()))
- .unwrap();
- let thunk = move |sender: &BackendEventConsumer| {
- debug!("refreshing");
- let mut path = path.clone();
- path.push("new");
- for d in path.read_dir()? {
- if let Ok(p) = d {
- move_to_cur(p.path()).ok().take();
- }
+ Ok(Box::pin(async move {
+ let thunk = move |sender: &BackendEventConsumer| {
+ debug!("refreshing");
+ let mut path = path.clone();
+ path.push("new");
+ for d in path.read_dir()? {
+ if let Ok(p) = d {
+ move_to_cur(p.path()).ok().take();
}
- path.pop();
+ }
+ path.pop();
- path.push("cur");
- let iter = path.read_dir()?;
- let count = path.read_dir()?.count();
- let mut files: Vec = Vec::with_capacity(count);
- for e in iter {
- let e = e.and_then(|x| {
- let path = x.path();
- Ok(path)
- })?;
- files.push(e);
- }
- let mut current_hashes = {
+ path.push("cur");
+ let iter = path.read_dir()?;
+ let count = path.read_dir()?.count();
+ let mut files: Vec = Vec::with_capacity(count);
+ for e in iter {
+ let e = e.and_then(|x| {
+ let path = x.path();
+ Ok(path)
+ })?;
+ files.push(e);
+ }
+ let mut current_hashes = {
+ let mut map = map.lock().unwrap();
+ let map = map.entry(mailbox_hash).or_default();
+ map.keys().cloned().collect::>()
+ };
+ for file in files {
+ let hash = get_file_hash(&file);
+ {
let mut map = map.lock().unwrap();
let map = map.entry(mailbox_hash).or_default();
- map.keys().cloned().collect::>()
- };
- for file in files {
- let hash = get_file_hash(&file);
- {
- let mut map = map.lock().unwrap();
- let map = map.entry(mailbox_hash).or_default();
- if map.contains_key(&hash) {
- map.remove(&hash);
- current_hashes.remove(&hash);
- continue;
- }
- (*map).insert(hash, PathBuf::from(&file).into());
+ if map.contains_key(&hash) {
+ map.remove(&hash);
+ current_hashes.remove(&hash);
+ continue;
}
- let op = Box::new(MaildirOp::new(hash, map.clone(), mailbox_hash));
- if let Ok(e) = Envelope::from_token(op, hash) {
- mailbox_index.lock().unwrap().insert(e.hash(), mailbox_hash);
- let file_name = file.strip_prefix(&root_path).unwrap().to_path_buf();
- if let Ok(cached) = cache_dir.place_cache_file(file_name) {
- /* place result in cache directory */
- let f = match fs::File::create(cached) {
- Ok(f) => f,
- Err(e) => {
- panic!("{}", e);
- }
- };
- let metadata = f.metadata().unwrap();
- let mut permissions = metadata.permissions();
+ (*map).insert(hash, PathBuf::from(&file).into());
+ }
+ let op = Box::new(MaildirOp::new(hash, map.clone(), mailbox_hash));
+ if let Ok(e) = Envelope::from_token(op, hash) {
+ mailbox_index.lock().unwrap().insert(e.hash(), mailbox_hash);
+ let file_name = file.strip_prefix(&root_path).unwrap().to_path_buf();
+ if let Ok(cached) = cache_dir.place_cache_file(file_name) {
+ /* place result in cache directory */
+ let f = match fs::File::create(cached) {
+ Ok(f) => f,
+ Err(e) => {
+ panic!("{}", e);
+ }
+ };
+ let metadata = f.metadata().unwrap();
+ let mut permissions = metadata.permissions();
- permissions.set_mode(0o600); // Read/write for owner only.
- f.set_permissions(permissions).unwrap();
+ permissions.set_mode(0o600); // Read/write for owner only.
+ f.set_permissions(permissions).unwrap();
- let writer = io::BufWriter::new(f);
- bincode::serialize_into(writer, &e).unwrap();
- }
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+ let writer = io::BufWriter::new(f);
+ bincode::serialize_into(writer, &e).unwrap();
+ }
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
account_hash,
mailbox_hash,
kind: Create(Box::new(e)),
- }));
- } else {
- debug!(
- "DEBUG: hash {}, path: {} couldn't be parsed",
- hash,
- file.as_path().display()
- );
- continue;
- }
+ }),
+ );
+ } else {
+ debug!(
+ "DEBUG: hash {}, path: {} couldn't be parsed",
+ hash,
+ file.as_path().display()
+ );
+ continue;
}
- for ev in current_hashes.into_iter().map(|h| BackendEvent::Refresh(RefreshEvent {
+ }
+ for ev in current_hashes.into_iter().map(|h| {
+ BackendEvent::Refresh(RefreshEvent {
account_hash,
mailbox_hash,
kind: Remove(h),
- })) {
- (sender)(account_hash, ev);
- }
- Ok(())
- };
- if let Err(err) = thunk(&sender) {
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+ })
+ }) {
+ (sender)(account_hash, ev);
+ }
+ Ok(())
+ };
+ if let Err(err) = thunk(&sender) {
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
account_hash,
mailbox_hash,
kind: Failure(err),
- }));
- }
- })
- };
- Ok(w.build(handle))
+ }),
+ );
+ }
+ Ok(())
+ }))
}
- fn watch(
- &self,
- work_context: WorkContext,
- ) -> Result {
+
+ fn watch(&self) -> ResultFuture<()> {
let sender = self.event_consumer.clone();
let (tx, rx) = channel();
let mut watcher = watcher(tx, Duration::from_secs(2)).unwrap();
@@ -365,335 +355,371 @@ impl MailBackend for MaildirType {
debug!("watching {:?}", root_path);
let hash_indexes = self.hash_indexes.clone();
let mailbox_index = self.mailbox_index.clone();
- let root_mailbox_hash: MailboxHash = self.mailboxes.values().find(|m| m.parent.is_none()).map(|m| m.hash()).unwrap();
+ let root_mailbox_hash: MailboxHash = self
+ .mailboxes
+ .values()
+ .find(|m| m.parent.is_none())
+ .map(|m| m.hash())
+ .unwrap();
let mailbox_counts = self
.mailboxes
.iter()
.map(|(&k, v)| (k, (v.unseen.clone(), v.total.clone())))
.collect::>, Arc>)>>();
- let handle = thread::Builder::new()
- .name("mailbox watch".to_string())
- .spawn(move || {
- // Move `watcher` in the closure's scope so that it doesn't get dropped.
- let _watcher = watcher;
- let _work_context = work_context;
- loop {
- match rx.recv() {
- /*
- * Event types:
- *
- * pub enum RefreshEventKind {
- * Update(EnvelopeHash, Envelope), // Old hash, new envelope
- * Create(Envelope),
- * Remove(EnvelopeHash),
- * Rescan,
- * }
- */
- Ok(event) => match event {
- /* Create */
- DebouncedEvent::Create(mut pathbuf) => {
- debug!("DebouncedEvent::Create(path = {:?}", pathbuf);
- if path_is_new!(pathbuf) {
- debug!("path_is_new");
- /* This creates a Rename event that we will receive later */
- pathbuf = match move_to_cur(pathbuf) {
- Ok(p) => p,
- Err(e) => {
- debug!("error: {}", e.to_string());
- continue;
- }
- };
-
-
+ Ok(Box::pin(async move {
+ // Move `watcher` in the closure's scope so that it doesn't get dropped.
+ let _watcher = watcher;
+ loop {
+ match rx.recv() {
+ /*
+ * Event types:
+ *
+ * pub enum RefreshEventKind {
+ * Update(EnvelopeHash, Envelope), // Old hash, new envelope
+ * Create(Envelope),
+ * Remove(EnvelopeHash),
+ * Rescan,
+ * }
+ */
+ Ok(event) => match event {
+ /* Create */
+ DebouncedEvent::Create(mut pathbuf) => {
+ debug!("DebouncedEvent::Create(path = {:?}", pathbuf);
+ if path_is_new!(pathbuf) {
+ debug!("path_is_new");
+ /* This creates a Rename event that we will receive later */
+ pathbuf = match move_to_cur(pathbuf) {
+ Ok(p) => p,
+ Err(e) => {
+ debug!("error: {}", e.to_string());
+ continue;
+ }
+ };
+ }
+ let mailbox_hash = get_path_hash!(pathbuf);
+ let file_name = pathbuf
+ .as_path()
+ .strip_prefix(&root_path)
+ .unwrap()
+ .to_path_buf();
+ if let Some(env) = add_path_to_index(
+ &hash_indexes,
+ mailbox_hash,
+ pathbuf.as_path(),
+ &cache_dir,
+ file_name,
+ ) {
+ mailbox_index
+ .lock()
+ .unwrap()
+ .insert(env.hash(), mailbox_hash);
+ debug!(
+ "Create event {} {} {}",
+ env.hash(),
+ env.subject(),
+ pathbuf.display()
+ );
+ if !env.is_seen() {
+ *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
}
- let mailbox_hash = get_path_hash!(pathbuf);
- let file_name = pathbuf
+ *mailbox_counts[&mailbox_hash].1.lock().unwrap() += 1;
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
+ account_hash,
+ mailbox_hash,
+ kind: Create(Box::new(env)),
+ }),
+ );
+ }
+ }
+ /* Update */
+ DebouncedEvent::NoticeWrite(pathbuf) | DebouncedEvent::Write(pathbuf) => {
+ debug!("DebouncedEvent::Write(path = {:?}", &pathbuf);
+ let mailbox_hash = get_path_hash!(pathbuf);
+ let mut hash_indexes_lock = hash_indexes.lock().unwrap();
+ let index_lock =
+ &mut hash_indexes_lock.entry(mailbox_hash).or_default();
+ let file_name = pathbuf
+ .as_path()
+ .strip_prefix(&root_path)
+ .unwrap()
+ .to_path_buf();
+ /* Linear search in hash_index to find old hash */
+ let old_hash: EnvelopeHash = {
+ if let Some((k, v)) =
+ index_lock.iter_mut().find(|(_, v)| *v.buf == pathbuf)
+ {
+ //TODO FIXME This doesn't make sense?
+ *v = pathbuf.clone().into();
+ *k
+ } else {
+ drop(hash_indexes_lock);
+ /* Did we just miss a Create event? In any case, create
+ * envelope. */
+ if let Some(env) = add_path_to_index(
+ &hash_indexes,
+ mailbox_hash,
+ pathbuf.as_path(),
+ &cache_dir,
+ file_name,
+ ) {
+ mailbox_index
+ .lock()
+ .unwrap()
+ .insert(env.hash(), mailbox_hash);
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
+ account_hash,
+ mailbox_hash,
+ kind: Create(Box::new(env)),
+ }),
+ );
+ }
+ continue;
+ }
+ };
+ let new_hash: EnvelopeHash = get_file_hash(pathbuf.as_path());
+ if index_lock.get_mut(&new_hash).is_none() {
+ debug!("write notice");
+ let op = Box::new(MaildirOp::new(
+ new_hash,
+ hash_indexes.clone(),
+ mailbox_hash,
+ ));
+ if let Ok(env) = Envelope::from_token(op, new_hash) {
+ debug!("{}\t{:?}", new_hash, &pathbuf);
+ debug!(
+ "hash {}, path: {:?} couldn't be parsed",
+ new_hash, &pathbuf
+ );
+ index_lock.insert(new_hash, pathbuf.into());
+
+ /* Send Write notice */
+
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
+ account_hash,
+ mailbox_hash,
+ kind: Update(old_hash, Box::new(env)),
+ }),
+ );
+ }
+ }
+ }
+ /* Remove */
+ DebouncedEvent::NoticeRemove(pathbuf) | DebouncedEvent::Remove(pathbuf) => {
+ debug!("DebouncedEvent::Remove(path = {:?}", pathbuf);
+ let mailbox_hash = get_path_hash!(pathbuf);
+ let mut hash_indexes_lock = hash_indexes.lock().unwrap();
+ let index_lock = hash_indexes_lock.entry(mailbox_hash).or_default();
+ let hash: EnvelopeHash = if let Some((k, _)) =
+ index_lock.iter().find(|(_, v)| *v.buf == pathbuf)
+ {
+ *k
+ } else {
+ debug!("removed but not contained in index");
+ continue;
+ };
+ if let Some(ref modif) = &index_lock[&hash].modified {
+ match modif {
+ PathMod::Path(path) => debug!(
+ "envelope {} has modified path set {}",
+ hash,
+ path.display()
+ ),
+ PathMod::Hash(hash) => debug!(
+ "envelope {} has modified path set {}",
+ hash,
+ &index_lock[&hash].buf.display()
+ ),
+ }
+ index_lock.entry(hash).and_modify(|e| {
+ e.removed = false;
+ });
+ continue;
+ }
+ *mailbox_counts[&mailbox_hash].1.lock().unwrap() -= 1;
+ if !pathbuf.flags().contains(Flag::SEEN) {
+ *mailbox_counts[&mailbox_hash].0.lock().unwrap() -= 1;
+ }
+
+ index_lock.entry(hash).and_modify(|e| {
+ e.removed = true;
+ });
+
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
+ account_hash,
+ mailbox_hash,
+ kind: Remove(hash),
+ }),
+ );
+ }
+ /* Envelope hasn't changed */
+ DebouncedEvent::Rename(src, dest) => {
+ debug!("DebouncedEvent::Rename(src = {:?}, dest = {:?})", src, dest);
+ let mailbox_hash = get_path_hash!(src);
+ let old_hash: EnvelopeHash = get_file_hash(src.as_path());
+ let new_hash: EnvelopeHash = get_file_hash(dest.as_path());
+
+ let mut hash_indexes_lock = hash_indexes.lock().unwrap();
+ let index_lock = hash_indexes_lock.entry(mailbox_hash).or_default();
+ let old_flags = src.flags();
+ let new_flags = dest.flags();
+ let was_seen: bool = old_flags.contains(Flag::SEEN);
+ let is_seen: bool = new_flags.contains(Flag::SEEN);
+
+ if index_lock.contains_key(&old_hash) && !index_lock[&old_hash].removed
+ {
+ debug!("contains_old_key");
+ index_lock.entry(old_hash).and_modify(|e| {
+ debug!(&e.modified);
+ e.modified = Some(PathMod::Hash(new_hash));
+ });
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
+ account_hash,
+ mailbox_hash: get_path_hash!(dest),
+ kind: Rename(old_hash, new_hash),
+ }),
+ );
+ if !was_seen && is_seen {
+ let mut lck = mailbox_counts[&mailbox_hash].0.lock().unwrap();
+ *lck = lck.saturating_sub(1);
+ } else if was_seen && !is_seen {
+ *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
+ }
+ if old_flags != new_flags {
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
+ account_hash,
+ mailbox_hash: get_path_hash!(dest),
+ kind: NewFlags(new_hash, (new_flags, vec![])),
+ }),
+ );
+ }
+ mailbox_index
+ .lock()
+ .unwrap()
+ .insert(new_hash, get_path_hash!(dest));
+ index_lock.insert(new_hash, dest.into());
+ continue;
+ } else if !index_lock.contains_key(&new_hash)
+ && index_lock
+ .get(&old_hash)
+ .map(|e| e.removed)
+ .unwrap_or(false)
+ {
+ if index_lock
+ .get(&old_hash)
+ .map(|e| e.removed)
+ .unwrap_or(false)
+ {
+ index_lock.entry(old_hash).and_modify(|e| {
+ e.modified = Some(PathMod::Hash(new_hash));
+ e.removed = false;
+ });
+ debug!("contains_old_key, key was marked as removed (by external source)");
+ } else {
+ debug!("not contains_new_key");
+ }
+ let file_name = dest
.as_path()
.strip_prefix(&root_path)
.unwrap()
.to_path_buf();
+ debug!("filename = {:?}", file_name);
+ drop(hash_indexes_lock);
if let Some(env) = add_path_to_index(
&hash_indexes,
mailbox_hash,
- pathbuf.as_path(),
+ dest.as_path(),
&cache_dir,
file_name,
) {
- mailbox_index.lock().unwrap().insert(env.hash(),mailbox_hash);
+ mailbox_index
+ .lock()
+ .unwrap()
+ .insert(env.hash(), mailbox_hash);
debug!(
"Create event {} {} {}",
env.hash(),
env.subject(),
- pathbuf.display()
+ dest.display()
);
if !env.is_seen() {
*mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
}
*mailbox_counts[&mailbox_hash].1.lock().unwrap() += 1;
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+ (sender)(
account_hash,
- mailbox_hash,
- kind: Create(Box::new(env)),
- }));
- }
- }
- /* Update */
- DebouncedEvent::NoticeWrite(pathbuf)
- | DebouncedEvent::Write(pathbuf) => {
- debug!("DebouncedEvent::Write(path = {:?}", &pathbuf);
- let mailbox_hash = get_path_hash!(pathbuf);
- let mut hash_indexes_lock = hash_indexes.lock().unwrap();
- let index_lock =
- &mut hash_indexes_lock.entry(mailbox_hash).or_default();
- let file_name = pathbuf
- .as_path()
- .strip_prefix(&root_path)
- .unwrap()
- .to_path_buf();
- /* Linear search in hash_index to find old hash */
- let old_hash: EnvelopeHash = {
- if let Some((k, v)) =
- index_lock.iter_mut().find(|(_, v)| *v.buf == pathbuf)
- {
- //TODO FIXME This doesn't make sense?
- *v = pathbuf.clone().into();
- *k
- } else {
- drop(hash_indexes_lock);
- /* Did we just miss a Create event? In any case, create
- * envelope. */
- if let Some(env) = add_path_to_index(
- &hash_indexes,
- mailbox_hash,
- pathbuf.as_path(),
- &cache_dir,
- file_name,
- ) {
- mailbox_index.lock().unwrap().insert(env.hash(),mailbox_hash);
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
- account_hash,
- mailbox_hash,
- kind: Create(Box::new(env)),
- }));
- }
- return;
- }
- };
- let new_hash: EnvelopeHash = get_file_hash(pathbuf.as_path());
- if index_lock.get_mut(&new_hash).is_none() {
- debug!("write notice");
- let op = Box::new(MaildirOp::new(
- new_hash,
- hash_indexes.clone(),
- mailbox_hash,
- ));
- if let Ok(env) = Envelope::from_token(op, new_hash) {
- debug!("{}\t{:?}", new_hash, &pathbuf);
- debug!(
- "hash {}, path: {:?} couldn't be parsed",
- new_hash, &pathbuf
- );
- index_lock.insert(new_hash, pathbuf.into());
-
- /* Send Write notice */
-
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
- account_hash,
- mailbox_hash,
- kind: Update(old_hash, Box::new(env)),
- }));
- }
- }
- }
- /* Remove */
- DebouncedEvent::NoticeRemove(pathbuf)
- | DebouncedEvent::Remove(pathbuf) => {
- debug!("DebouncedEvent::Remove(path = {:?}", pathbuf);
- let mailbox_hash = get_path_hash!(pathbuf);
- let mut hash_indexes_lock = hash_indexes.lock().unwrap();
- let index_lock = hash_indexes_lock.entry(mailbox_hash).or_default();
- let hash: EnvelopeHash = if let Some((k, _)) =
- index_lock.iter().find(|(_, v)| *v.buf == pathbuf)
- {
- *k
- } else {
- debug!("removed but not contained in index");
- continue;
- };
- if let Some(ref modif) = &index_lock[&hash].modified {
- match modif {
- PathMod::Path(path) => debug!(
- "envelope {} has modified path set {}",
- hash,
- path.display()
- ),
- PathMod::Hash(hash) => debug!(
- "envelope {} has modified path set {}",
- hash,
- &index_lock[&hash].buf.display()
- ),
- }
- index_lock.entry(hash).and_modify(|e| {
- e.removed = false;
- });
- continue;
- }
- *mailbox_counts[&mailbox_hash].1.lock().unwrap() -= 1;
- if !pathbuf.flags().contains(Flag::SEEN) {
- *mailbox_counts[&mailbox_hash].0.lock().unwrap() -= 1;
- }
-
- index_lock.entry(hash).and_modify(|e| {
- e.removed = true;
- });
-
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
- account_hash,
- mailbox_hash,
- kind: Remove(hash),
- }));
- }
- /* Envelope hasn't changed */
- DebouncedEvent::Rename(src, dest) => {
- debug!(
- "DebouncedEvent::Rename(src = {:?}, dest = {:?})",
- src, dest
- );
- let mailbox_hash = get_path_hash!(src);
- let old_hash: EnvelopeHash = get_file_hash(src.as_path());
- let new_hash: EnvelopeHash = get_file_hash(dest.as_path());
-
- let mut hash_indexes_lock = hash_indexes.lock().unwrap();
- let index_lock = hash_indexes_lock.entry(mailbox_hash).or_default();
- let old_flags = src.flags();
- let new_flags = dest.flags();
- let was_seen: bool = old_flags.contains(Flag::SEEN);
- let is_seen: bool = new_flags.contains(Flag::SEEN);
-
- if index_lock.contains_key(&old_hash)
- && !index_lock[&old_hash].removed
- {
- debug!("contains_old_key");
- index_lock.entry(old_hash).and_modify(|e| {
- debug!(&e.modified);
- e.modified = Some(PathMod::Hash(new_hash));
- });
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
- account_hash,
- mailbox_hash: get_path_hash!(dest),
- kind: Rename(old_hash, new_hash),
- }));
- if !was_seen && is_seen {
- let mut lck = mailbox_counts[&mailbox_hash].0.lock().unwrap();
- *lck = lck.saturating_sub(1);
- } else if was_seen && !is_seen {
- *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
- }
- if old_flags != new_flags {
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
- account_hash,
- mailbox_hash: get_path_hash!(dest),
- kind: NewFlags(new_hash, (new_flags, vec![])),
- }));
- }
- mailbox_index.lock().unwrap().insert(new_hash,get_path_hash!(dest) );
- index_lock.insert(new_hash, dest.into());
- continue;
- } else if !index_lock.contains_key(&new_hash)
- && index_lock
- .get(&old_hash)
- .map(|e| e.removed)
- .unwrap_or(false)
- {
- if index_lock
- .get(&old_hash)
- .map(|e| e.removed)
- .unwrap_or(false)
- {
- index_lock.entry(old_hash).and_modify(|e| {
- e.modified = Some(PathMod::Hash(new_hash));
- e.removed = false;
- });
- debug!("contains_old_key, key was marked as removed (by external source)");
- } else {
- debug!("not contains_new_key");
- }
- let file_name = dest
- .as_path()
- .strip_prefix(&root_path)
- .unwrap()
- .to_path_buf();
- debug!("filename = {:?}", file_name);
- drop(hash_indexes_lock);
- if let Some(env) = add_path_to_index(
- &hash_indexes,
- mailbox_hash,
- dest.as_path(),
- &cache_dir,
- file_name,
- ) {
- mailbox_index.lock().unwrap().insert(env.hash(), mailbox_hash);
- debug!(
- "Create event {} {} {}",
- env.hash(),
- env.subject(),
- dest.display()
- );
- if !env.is_seen() {
- *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
- }
- *mailbox_counts[&mailbox_hash].1.lock().unwrap() += 1;
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+ BackendEvent::Refresh(RefreshEvent {
account_hash,
mailbox_hash,
kind: Create(Box::new(env)),
- }));
- continue;
- } else {
- debug!("not valid email");
- }
+ }),
+ );
+ continue;
} else {
- if was_seen && !is_seen {
- *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
- }
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+ debug!("not valid email");
+ }
+ } else {
+ if was_seen && !is_seen {
+ *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
+ }
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
account_hash,
mailbox_hash: get_path_hash!(dest),
kind: Rename(old_hash, new_hash),
- }));
- debug!("contains_new_key");
- if old_flags != new_flags {
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+ }),
+ );
+ debug!("contains_new_key");
+ if old_flags != new_flags {
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
account_hash,
mailbox_hash: get_path_hash!(dest),
kind: NewFlags(new_hash, (new_flags, vec![])),
- }));
- }
+ }),
+ );
}
-
- /* Maybe a re-read should be triggered here just to be safe.
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
- account_hash,
- mailbox_hash: get_path_hash!(dest),
- kind: Rescan,
- }));
- */
}
- /* Trigger rescan of mailbox */
- DebouncedEvent::Rescan => {
- (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+
+ /* Maybe a re-read should be triggered here just to be safe.
+ (sender)(account_hash, BackendEvent::Refresh(RefreshEvent {
+ account_hash,
+ mailbox_hash: get_path_hash!(dest),
+ kind: Rescan,
+ }));
+ */
+ }
+ /* Trigger rescan of mailbox */
+ DebouncedEvent::Rescan => {
+ (sender)(
+ account_hash,
+ BackendEvent::Refresh(RefreshEvent {
account_hash,
mailbox_hash: root_mailbox_hash,
kind: Rescan,
- }));
- }
- _ => {}
- },
- Err(e) => debug!("watch error: {:?}", e),
- }
+ }),
+ );
+ }
+ _ => {}
+ },
+ Err(e) => debug!("watch error: {:?}", e),
}
- })?;
- Ok(handle.thread().id())
+ }
+ Ok(())
+ }))
}
fn operation(&self, hash: EnvelopeHash) -> Result> {
@@ -832,8 +858,8 @@ impl MailBackend for MaildirType {
};
self.mailboxes.insert(mailbox_hash, new_mailbox);
- let ret = Ok((mailbox_hash, self.mailboxes()?));
- Ok(Box::pin(async { ret }))
+ let ret = self.mailboxes()?;
+ Ok(Box::pin(async move { Ok((mailbox_hash, ret.await?)) }))
}
fn delete_mailbox(
@@ -1019,7 +1045,12 @@ impl MaildirType {
}))
}
- pub fn multicore(&mut self, cores: usize, mailbox_hash: MailboxHash) -> Async>> {
+ /*
+ pub fn multicore(
+ &mut self,
+ cores: usize,
+ mailbox_hash: MailboxHash,
+ ) -> Async>> {
let mut w = AsyncBuilder::new();
let cache_dir = xdg::BaseDirectories::with_profile("meli", &self.name).unwrap();
@@ -1199,6 +1230,7 @@ impl MaildirType {
};
w.build(handle)
}
+ */
pub fn save_to_mailbox(mut path: PathBuf, bytes: Vec, flags: Option) -> Result<()> {
for d in &["cur", "new", "tmp"] {
diff --git a/melib/src/backends/mbox.rs b/melib/src/backends/mbox.rs
index c0224807..7c150cba 100644
--- a/melib/src/backends/mbox.rs
+++ b/melib/src/backends/mbox.rs
@@ -23,7 +23,6 @@
* https://wiki2.dovecot.org/MailboxFormat/mbox
*/
-use crate::async_workers::{Async, AsyncBuilder, AsyncStatus, WorkContext};
use crate::backends::*;
use crate::conf::AccountSettings;
use crate::email::parser::BytesExt;
@@ -707,96 +706,109 @@ impl MailBackend for MboxType {
CAPABILITIES
}
- fn is_online(&self) -> Result<()> {
- Ok(())
+ fn is_online(&self) -> ResultFuture<()> {
+ Ok(Box::pin(async { Ok(()) }))
}
- fn fetch(&mut self, mailbox_hash: MailboxHash) -> Result>>> {
- let mut w = AsyncBuilder::new();
- let handle = {
- let tx = w.tx();
- let mailbox_index = self.mailbox_index.clone();
- let mailboxes = self.mailboxes.clone();
- let mailbox_path = mailboxes.lock().unwrap()[&mailbox_hash].fs_path.clone();
- let prefer_mbox_type = self.prefer_mbox_type;
- let closure = move |_work_context| {
- let tx = tx.clone();
- let file = match std::fs::OpenOptions::new()
- .read(true)
- .write(true)
- .open(&mailbox_path)
- {
- Ok(f) => f,
- Err(e) => {
- tx.send(AsyncStatus::Payload(Err(MeliError::from(e))))
- .unwrap();
- return;
- }
- };
- get_rw_lock_blocking(&file);
- let mut buf_reader = BufReader::new(file);
- let mut contents = Vec::new();
- if let Err(e) = buf_reader.read_to_end(&mut contents) {
- tx.send(AsyncStatus::Payload(Err(MeliError::from(e))))
- .unwrap();
- return;
- };
-
- let mailboxes_lck = mailboxes.lock().unwrap();
- let index = mailboxes_lck[&mailbox_hash].index.clone();
+ fn fetch(
+ &mut self,
+ mailbox_hash: MailboxHash,
+ ) -> Result>> + Send + 'static>>> {
+ struct FetchState {
+ mailbox_hash: MailboxHash,
+ mailbox_index: Arc>>,
+ mailboxes: Arc>>,
+ prefer_mbox_type: Option,
+ offset: usize,
+ file_offset: usize,
+ contents: Vec,
+ }
+ impl FetchState {
+ async fn fetch(&mut self) -> Result