summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-06-30 11:40:26 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-07-06 15:26:00 +0300
commite06308fed26e0730b2f8a15880a371cd38bfdf20 (patch)
tree47465e3d5a8098bc6f391ce1acfc3b5e69c8a150
parent03522c0298a50cdb943664f2786f6a58eebce828 (diff)
MailBackend: change more methods to Futures
-rw-r--r--melib/src/backends.rs53
-rw-r--r--melib/src/backends/imap.rs66
-rw-r--r--melib/src/backends/imap/protocol_parser.rs1
-rw-r--r--melib/src/backends/imap_async.rs110
-rw-r--r--melib/src/backends/imap_async/connection.rs1
-rw-r--r--melib/src/backends/imap_async/protocol_parser.rs1
-rw-r--r--melib/src/backends/jmap.rs13
-rw-r--r--melib/src/backends/maildir/backend.rs47
-rw-r--r--melib/src/backends/mbox.rs7
-rw-r--r--melib/src/backends/notmuch.rs10
-rw-r--r--src/components/mail/listing.rs8
-rw-r--r--src/components/mail/listing/compact.rs59
-rw-r--r--src/components/mail/listing/conversations.rs169
-rw-r--r--src/components/mail/listing/offline.rs2
-rw-r--r--src/components/mail/listing/plain.rs147
-rw-r--r--src/components/utilities.rs37
-rw-r--r--src/components/utilities/widgets.rs23
-rw-r--r--src/conf/accounts.rs232
-rw-r--r--src/plugins/backend.rs9
-rw-r--r--src/types.rs2
-rw-r--r--src/unix.rs6
21 files changed, 611 insertions, 392 deletions
diff --git a/melib/src/backends.rs b/melib/src/backends.rs
index 4fe74859..6d0ce570 100644
--- a/melib/src/backends.rs
+++ b/melib/src/backends.rs
@@ -295,11 +295,11 @@ impl NotifyFn {
}
}
+pub type ResultFuture<T> = Result<Pin<Box<dyn Future<Output = Result<T>> + Send + 'static>>>;
+
pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
fn is_online(&self) -> Result<()>;
- fn is_online_async(
- &self,
- ) -> Result<Pin<Box<dyn Future<Output = Result<()>> + Send + 'static>>> {
+ fn is_online_async(&self) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
fn connect(&mut self) {}
@@ -321,7 +321,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
&mut self,
_mailbox_hash: MailboxHash,
_sender: RefreshEventConsumer,
- ) -> Result<Pin<Box<dyn Future<Output = Result<()>> + Send + 'static>>> {
+ ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
fn watch(
@@ -330,15 +330,18 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
work_context: WorkContext,
) -> Result<std::thread::ThreadId>;
fn mailboxes(&self) -> Result<HashMap<MailboxHash, Mailbox>>;
- fn mailboxes_async(
- &self,
- ) -> Result<Pin<Box<dyn Future<Output = Result<HashMap<MailboxHash, Mailbox>>> + Send>>> {
+ fn mailboxes_async(&self) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
Err(MeliError::new("Unimplemented."))
}
fn operation(&self, hash: EnvelopeHash) -> Result<Box<dyn BackendOp>>;
- fn save(&self, bytes: &[u8], mailbox_hash: MailboxHash, flags: Option<Flag>) -> Result<()>;
- fn delete(&self, _env_hash: EnvelopeHash, _mailbox_hash: MailboxHash) -> Result<()> {
+ fn save(
+ &self,
+ bytes: Vec<u8>,
+ mailbox_hash: MailboxHash,
+ flags: Option<Flag>,
+ ) -> ResultFuture<()>;
+ fn delete(&self, _env_hash: EnvelopeHash, _mailbox_hash: MailboxHash) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
@@ -353,22 +356,30 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
fn create_mailbox(
&mut self,
_path: String,
- ) -> Result<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
+ ) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
Err(MeliError::new("Unimplemented."))
}
fn delete_mailbox(
&mut self,
_mailbox_hash: MailboxHash,
- ) -> Result<HashMap<MailboxHash, Mailbox>> {
+ ) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
Err(MeliError::new("Unimplemented."))
}
- fn set_mailbox_subscription(&mut self, _mailbox_hash: MailboxHash, _val: bool) -> Result<()> {
+ fn set_mailbox_subscription(
+ &mut self,
+ _mailbox_hash: MailboxHash,
+ _val: bool,
+ ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
- fn rename_mailbox(&mut self, _mailbox_hash: MailboxHash, _new_path: String) -> Result<Mailbox> {
+ fn rename_mailbox(
+ &mut self,
+ _mailbox_hash: MailboxHash,
+ _new_path: String,
+ ) -> ResultFuture<Mailbox> {
Err(MeliError::new("Unimplemented."))
}
@@ -376,7 +387,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
&mut self,
_mailbox_hash: MailboxHash,
_val: MailboxPermissions,
- ) -> Result<()> {
+ ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
@@ -384,7 +395,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
&self,
_query: crate::search::Query,
_mailbox_hash: Option<MailboxHash>,
- ) -> Result<SmallVec<[EnvelopeHash; 512]>> {
+ ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
Err(MeliError::new("Unimplemented."))
}
}
@@ -469,18 +480,10 @@ impl BackendOp for ReadOnlyOp {
fn fetch_flags(&self) -> Result<Flag> {
self.op.fetch_flags()
}
- fn set_flag(
- &mut self,
- _flag: Flag,
- _value: bool,
- ) -> Result<Pin<Box<dyn Future<Output = Result<()>> + Send>>> {
+ fn set_flag(&mut self, _flag: Flag, _value: bool) -> ResultFuture<()> {
Err(MeliError::new("read-only set."))
}
- fn set_tag(
- &mut self,
- _tag: String,
- _value: bool,
- ) -> Result<Pin<Box<dyn Future<Output = Result<()>> + Send>>> {
+ fn set_tag(&mut self, _tag: String, _value: bool) -> ResultFuture<()> {
Err(MeliError::new("read-only set."))
}
}
diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs
index ee748e7c..8c9f37f7 100644
--- a/melib/src/backends/imap.rs
+++ b/melib/src/backends/imap.rs
@@ -37,11 +37,10 @@ pub mod managesieve;
mod untagged;
use crate::async_workers::{Async, AsyncBuilder, AsyncStatus, WorkContext};
-use crate::backends::BackendOp;
-use crate::backends::RefreshEvent;
-use crate::backends::RefreshEventKind::{self, *};
-use crate::backends::{AccountHash, MailboxHash};
-use crate::backends::{BackendMailbox, MailBackend, Mailbox, RefreshEventConsumer};
+use crate::backends::{
+ RefreshEventKind::{self, *},
+ *,
+};
use crate::conf::AccountSettings;
use crate::email::*;
use crate::error::{MeliError, Result, ResultIntoMeliError};
@@ -665,7 +664,12 @@ impl MailBackend for ImapType {
)))
}
- fn save(&self, bytes: &[u8], mailbox_hash: MailboxHash, flags: Option<Flag>) -> Result<()> {
+ fn save(
+ &self,
+ bytes: Vec<u8>,
+ mailbox_hash: MailboxHash,
+ flags: Option<Flag>,
+ ) -> ResultFuture<()> {
let path = {
let mailboxes = self.uid_store.mailboxes.read().unwrap();
@@ -696,16 +700,16 @@ impl MailBackend for ImapType {
)?;
// wait for "+ Ready for literal data" reply
conn.wait_for_continuation_request()?;
- conn.send_literal(bytes)?;
+ conn.send_literal(&bytes)?;
conn.read_response(&mut response, RequiredResponses::empty())?;
- Ok(())
+ Ok(Box::pin(async { Ok(()) }))
}
- fn as_any(&self) -> &dyn::std::any::Any {
+ fn as_any(&self) -> &dyn ::std::any::Any {
self
}
- fn as_any_mut(&mut self) -> &mut dyn::std::any::Any {
+ fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
self
}
@@ -720,7 +724,7 @@ impl MailBackend for ImapType {
fn create_mailbox(
&mut self,
mut path: String,
- ) -> Result<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
+ ) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
/* Must transform path to something the IMAP server will accept
*
* Each root mailbox has a hierarchy delimeter reported by the LIST entry. All paths
@@ -768,13 +772,15 @@ impl MailBackend for ImapType {
let new_hash = get_path_hash!(path.as_str());
mailboxes.clear();
drop(mailboxes);
- Ok((new_hash, self.mailboxes().map_err(|err| MeliError::new(format!("Mailbox create was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err)))?))
+ let ret =
+ Ok((new_hash, self.mailboxes().map_err(|err| MeliError::new(format!("Mailbox create was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err)))?));
+ Ok(Box::pin(async { ret }))
}
fn delete_mailbox(
&mut self,
mailbox_hash: MailboxHash,
- ) -> Result<HashMap<MailboxHash, Mailbox>> {
+ ) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
let mailboxes = self.uid_store.mailboxes.read().unwrap();
let permissions = mailboxes[&mailbox_hash].permissions();
if !permissions.delete_mailbox {
@@ -812,13 +818,19 @@ impl MailBackend for ImapType {
let mut mailboxes = self.uid_store.mailboxes.write().unwrap();
mailboxes.clear();
drop(mailboxes);
- self.mailboxes().map_err(|err| format!("Mailbox delete was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err).into())
+ let res = self.mailboxes().map_err(|err| format!("Mailbox delete was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err).into());
+
+ Ok(Box::pin(async { res }))
}
- fn set_mailbox_subscription(&mut self, mailbox_hash: MailboxHash, new_val: bool) -> Result<()> {
+ fn set_mailbox_subscription(
+ &mut self,
+ mailbox_hash: MailboxHash,
+ new_val: bool,
+ ) -> ResultFuture<()> {
let mut mailboxes = self.uid_store.mailboxes.write().unwrap();
if mailboxes[&mailbox_hash].is_subscribed() == new_val {
- return Ok(());
+ return Ok(Box::pin(async { Ok(()) }));
}
let mut response = String::with_capacity(8 * 1024);
@@ -842,14 +854,14 @@ impl MailBackend for ImapType {
let _ = entry.set_is_subscribed(new_val);
});
}
- ret
+ Ok(Box::pin(async { ret }))
}
fn rename_mailbox(
&mut self,
mailbox_hash: MailboxHash,
mut new_path: String,
- ) -> Result<Mailbox> {
+ ) -> ResultFuture<Mailbox> {
let mut mailboxes = self.uid_store.mailboxes.write().unwrap();
let permissions = mailboxes[&mailbox_hash].permissions();
if !permissions.delete_mailbox {
@@ -880,30 +892,31 @@ impl MailBackend for ImapType {
mailboxes.clear();
drop(mailboxes);
self.mailboxes().map_err(|err| format!("Mailbox rename was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err))?;
- Ok(BackendMailbox::clone(
+
+ let ret = Ok(BackendMailbox::clone(
&self.uid_store.mailboxes.read().unwrap()[&new_hash],
- ))
+ ));
+ Ok(Box::pin(async { ret }))
}
fn set_mailbox_permissions(
&mut self,
mailbox_hash: MailboxHash,
- _val: crate::backends::MailboxPermissions,
- ) -> Result<()> {
+ _val: MailboxPermissions,
+ ) -> ResultFuture<()> {
let mailboxes = self.uid_store.mailboxes.write().unwrap();
let permissions = mailboxes[&mailbox_hash].permissions();
if !permissions.change_permissions {
return Err(MeliError::new(format!("You do not have permission to change permissions for mailbox `{}`. Set permissions for this mailbox are {}", mailboxes[&mailbox_hash].name(), permissions)));
}
-
- Err(MeliError::new("Unimplemented."))
+ Ok(Box::pin(async { Err(MeliError::new("Unimplemented.")) }))
}
fn search(
&self,
query: crate::search::Query,
mailbox_hash: Option<MailboxHash>,
- ) -> Result<SmallVec<[EnvelopeHash; 512]>> {
+ ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
if mailbox_hash.is_none() {
return Err(MeliError::new(
"Cannot search without specifying mailbox on IMAP",
@@ -1011,7 +1024,7 @@ impl MailBackend for ImapType {
if l.starts_with("* SEARCH") {
use std::iter::FromIterator;
let uid_index = self.uid_store.uid_index.lock()?;
- return Ok(SmallVec::from_iter(
+ let ret = Ok(SmallVec::from_iter(
l["* SEARCH".len()..]
.trim()
.split_whitespace()
@@ -1020,6 +1033,7 @@ impl MailBackend for ImapType {
.filter_map(|uid| uid_index.get(&(mailbox_hash, uid)))
.map(|env_hash_ref| *env_hash_ref),
));
+ return Ok(Box::pin(async { ret }));
}
}
Err(MeliError::new(response))
diff --git a/melib/src/backends/imap/protocol_parser.rs b/melib/src/backends/imap/protocol_parser.rs
index ec673c81..bd1545f4 100644
--- a/melib/src/backends/imap/protocol_parser.rs
+++ b/melib/src/backends/imap/protocol_parser.rs
@@ -355,7 +355,6 @@ pub fn list_mailbox_result(input: &[u8]) -> IResult<&[u8], ImapMailbox> {
f.no_select = false;
f.is_subscribed = false;
for p in properties.split(|&b| b == b' ') {
- use crate::backends::SpecialUsageMailbox;
if p.eq_ignore_ascii_case(b"\\NoSelect") {
f.no_select = true;
} else if p.eq_ignore_ascii_case(b"\\Sent") {
diff --git a/melib/src/backends/imap_async.rs b/melib/src/backends/imap_async.rs
index 368777d8..717b3c67 100644
--- a/melib/src/backends/imap_async.rs
+++ b/melib/src/backends/imap_async.rs
@@ -37,11 +37,10 @@ pub mod managesieve;
mod untagged;
use crate::async_workers::{Async, WorkContext};
-use crate::backends::BackendOp;
-use crate::backends::RefreshEvent;
-use crate::backends::RefreshEventKind::{self, *};
-use crate::backends::{AccountHash, MailboxHash};
-use crate::backends::{BackendMailbox, MailBackend, Mailbox, RefreshEventConsumer};
+use crate::backends::{
+ RefreshEventKind::{self, *},
+ *,
+};
use crate::conf::AccountSettings;
use crate::email::*;
use crate::error::{MeliError, Result, ResultIntoMeliError};
@@ -204,7 +203,7 @@ impl MailBackend for ImapType {
&mut self,
mailbox_hash: MailboxHash,
sender: RefreshEventConsumer,
- ) -> Result<Pin<Box<dyn Future<Output = Result<()>> + Send + 'static>>> {
+ ) -> ResultFuture<()> {
let inbox = self
.uid_store
.mailboxes
@@ -223,11 +222,7 @@ impl MailBackend for ImapType {
}))
}
- fn mailboxes_async(
- &self,
- ) -> Result<
- core::pin::Pin<Box<dyn Future<Output = Result<HashMap<MailboxHash, Mailbox>>> + Send>>,
- > {
+ fn mailboxes_async(&self) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
let uid_store = self.uid_store.clone();
let connection = self.connection.clone();
Ok(Box::pin(async move {
@@ -279,9 +274,7 @@ impl MailBackend for ImapType {
}))
}
- fn is_online_async(
- &self,
- ) -> Result<core::pin::Pin<Box<dyn Future<Output = Result<()>> + Send>>> {
+ fn is_online_async(&self) -> ResultFuture<()> {
let connection = self.connection.clone();
Ok(Box::pin(async move {
debug!("INSIDE is_online_async()");
@@ -392,7 +385,12 @@ impl MailBackend for ImapType {
)))
}
- fn save(&self, _bytes: &[u8], _mailbox_hash: MailboxHash, _flags: Option<Flag>) -> Result<()> {
+ fn save(
+ &self,
+ _bytes: Vec<u8>,
+ _mailbox_hash: MailboxHash,
+ _flags: Option<Flag>,
+ ) -> ResultFuture<()> {
unimplemented!()
/*
let path = {
@@ -450,7 +448,7 @@ impl MailBackend for ImapType {
fn create_mailbox(
&mut self,
_path: String,
- ) -> Result<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
+ ) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
unimplemented!()
/*
/* Must transform path to something the IMAP server will accept
@@ -507,7 +505,7 @@ impl MailBackend for ImapType {
fn delete_mailbox(
&mut self,
_mailbox_hash: MailboxHash,
- ) -> Result<HashMap<MailboxHash, Mailbox>> {
+ ) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
unimplemented!()
/*
let mailboxes = self.uid_store.mailboxes.read().unwrap();
@@ -553,7 +551,7 @@ impl MailBackend for ImapType {
&mut self,
_mailbox_hash: MailboxHash,
_new_val: bool,
- ) -> Result<()> {
+ ) -> ResultFuture<()> {
unimplemented!()
/*
let mut mailboxes = self.uid_store.mailboxes.write().unwrap();
@@ -586,7 +584,11 @@ impl MailBackend for ImapType {
*/
}
- fn rename_mailbox(&mut self, _mailbox_hash: MailboxHash, _new_path: String) -> Result<Mailbox> {
+ fn rename_mailbox(
+ &mut self,
+ _mailbox_hash: MailboxHash,
+ _new_path: String,
+ ) -> ResultFuture<Mailbox> {
unimplemented!()
/*
let mut mailboxes = self.uid_store.mailboxes.write().unwrap();
@@ -629,7 +631,7 @@ impl MailBackend for ImapType {
&mut self,
_mailbox_hash: MailboxHash,
_val: crate::backends::MailboxPermissions,
- ) -> Result<()> {
+ ) -> ResultFuture<()> {
unimplemented!()
/*
let mailboxes = self.uid_store.mailboxes.write().unwrap();
@@ -644,11 +646,9 @@ impl MailBackend for ImapType {
fn search(
&self,
- _query: crate::search::Query,
- _mailbox_hash: Option<MailboxHash>,
- ) -> Result<SmallVec<[EnvelopeHash; 512]>> {
- unimplemented!()
- /*
+ query: crate::search::Query,
+ mailbox_hash: Option<MailboxHash>,
+ ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
if mailbox_hash.is_none() {
return Err(MeliError::new(
"Cannot search without specifying mailbox on IMAP",
@@ -743,32 +743,38 @@ impl MailBackend for ImapType {
}
let mut query_str = String::new();
rec(&query, &mut query_str);
+ let connection = self.connection.clone();
+ let uid_store = self.uid_store.clone();
- let mut response = String::with_capacity(8 * 1024);
- let mut conn = try_lock(&self.connection, Some(std::time::Duration::new(2, 0)))?;
- conn.examine_mailbox(mailbox_hash, &mut response)?;
- conn.send_command(format!("UID SEARCH CHARSET UTF-8 {}", query_str).as_bytes())?;
- conn.read_response(&mut response, RequiredResponses::SEARCH)?;
- debug!(&response);
-
- let mut lines = response.lines();
- for l in lines.by_ref() {
- if l.starts_with("* SEARCH") {
- use std::iter::FromIterator;
- let uid_index = self.uid_store.uid_index.lock()?;
- return Ok(SmallVec::from_iter(
- l["* SEARCH".len()..]
- .trim()
- .split_whitespace()
- .map(usize::from_str)
- .filter_map(std::result::Result::ok)
- .filter_map(|uid| uid_index.get(&(mailbox_hash, uid)))
- .map(|env_hash_ref| *env_hash_ref),
- ));
+ Ok(Box::pin(async move {
+ let mut response = String::with_capacity(8 * 1024);
+ let mut conn = connection.lock().await;
+ conn.examine_mailbox(mailbox_hash, &mut response, false)
+ .await?;
+ conn.send_command(format!("UID SEARCH CHARSET UTF-8 {}", query_str).as_bytes())
+ .await?;
+ conn.read_response(&mut response, RequiredResponses::SEARCH)
+ .await?;
+ debug!(&response);
+
+ let mut lines = response.lines();
+ for l in lines.by_ref() {
+ if l.starts_with("* SEARCH") {
+ use std::iter::FromIterator;
+ let uid_index = uid_store.uid_index.lock()?;
+ return Ok(SmallVec::from_iter(
+ l["* SEARCH".len()..]
+ .trim()
+ .split_whitespace()
+ .map(usize::from_str)
+ .filter_map(std::result::Result::ok)
+ .filter_map(|uid| uid_index.get(&(mailbox_hash, uid)))
+ .map(|env_hash_ref| *env_hash_ref),
+ ));
+ }
}
- }
- Err(MeliError::new(response))
- */
+ Err(MeliError::new(response))
+ }))
}
}
@@ -1206,6 +1212,7 @@ async fn get_hlpr(
h.write_usize(uid);
h.write(mailbox_path.as_bytes());
env.set_hash(h.finish());
+ /*
debug!(
"env hash {} {} UID = {} MSN = {}",
env.hash(),
@@ -1213,6 +1220,7 @@ async fn get_hlpr(
uid,
message_sequence_number
);
+ */
valid_hash_set.insert(env.hash());
let mut tag_lck = uid_store.tag_index.write().unwrap();
if let Some((flags, keywords)) = flags {
@@ -1273,7 +1281,6 @@ async fn get_hlpr(
kind: RefreshEventKind::Remove(env_hash),
});
}
- drop(conn);
unseen
.lock()
.unwrap()
@@ -1282,9 +1289,10 @@ async fn get_hlpr(
.lock()
.unwrap()
.insert_existing_set(envelopes.iter().map(|(_, env)| env.hash()).collect::<_>());
+ drop(conn);
payload.extend(envelopes.into_iter().map(|(_, env)| env));
}
- *max_uid = if max_uid_left == 1 {
+ *max_uid = if max_uid_left <= 1 {
Some(0)
} else {
Some(std::cmp::max(
diff --git a/melib/src/backends/imap_async/connection.rs b/melib/src/backends/imap_async/connection.rs
index 362f9c63..e1653c1b 100644
--- a/melib/src/backends/imap_async/connection.rs
+++ b/melib/src/backends/imap_async/connection.rs
@@ -508,7 +508,6 @@ impl ImapConnection {
if required_responses.check(l) || !self.process_untagged(l).await? {
ret.push_str(l);
}
- ret.push_str(l);
}
}
}
diff --git a/melib/src/backends/imap_async/protocol_parser.rs b/melib/src/backends/imap_async/protocol_parser.rs
index 5823d69e..dbcc29d9 100644
--- a/melib/src/backends/imap_async/protocol_parser.rs
+++ b/melib/src/backends/imap_async/protocol_parser.rs
@@ -355,7 +355,6 @@ pub fn list_mailbox_result(input: &[u8]) -> IResult<&[u8], ImapMailbox> {
f.no_select = false;
f.is_subscribed = false;
for p in properties.split(|&b| b == b' ') {
- use crate::backends::SpecialUsageMailbox;
if p.eq_ignore_ascii_case(b"\\NoSelect") {
f.no_select = true;
} else if p.eq_ignore_ascii_case(b"\\Sent") {
diff --git a/melib/src/backends/jmap.rs b/melib/src/backends/jmap.rs
index 2999fcb0..5228c452 100644
--- a/melib/src/backends/jmap.rs
+++ b/melib/src/backends/jmap.rs
@@ -20,9 +20,7 @@
*/
use crate::async_workers::{Async, AsyncBuilder, AsyncStatus, WorkContext};
-use crate::backends::BackendOp;
-use crate::backends::MailboxHash;
-use crate::backends::{BackendMailbox, MailBackend, Mailbox, RefreshEventConsumer};
+use crate::backends::*;
use crate::conf::AccountSettings;
use crate::email::*;
use crate::error::{MeliError, Result};
@@ -262,11 +260,16 @@ impl MailBackend for JmapType {
)))
}
- fn save(&self, _bytes: &[u8], _mailbox_hash: MailboxHash, _flags: Option<Flag>) -> Result<()> {
+ fn save(
+ &self,
+ _bytes: Vec<u8>,
+ _mailbox_hash: MailboxHash,
+ _flags: Option<Flag>,
+ ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
- fn as_any(&self) -> &dyn::std::any::Any {
+ fn as_any(&self) -> &dyn ::std::any::Any {
self
}
diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs
index 5a463cd2..d24cdee8 100644
--- a/melib/src/backends/maildir/backend.rs
+++ b/melib/src/backends/maildir/backend.rs
@@ -178,6 +178,10 @@ impl MailBackend for MaildirType {
Ok(())
}
+ fn is_online_async(&self) -> ResultFuture<()> {
+ Ok(Box::pin(async { Ok(()) }))
+ }
+
fn mailboxes(&self) -> Result<HashMap<MailboxHash, Mailbox>> {
Ok(self
.mailboxes
@@ -185,6 +189,10 @@ impl MailBackend for MaildirType {
.map(|(h, f)| (*h, BackendMailbox::clone(f)))
.collect())
}
+ fn mailboxes_async(&self) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
+ let res = self.mailboxes();
+ Ok(Box::pin(async { res }))
+ }
fn get(&mut self, mailbox: &Mailbox) -> Async<Result<Vec<Envelope>>> {
self.multicore(4, mailbox)
@@ -670,18 +678,26 @@ impl MailBackend for MaildirType {
)))
}
- fn save(&self, bytes: &[u8], mailbox_hash: MailboxHash, flags: Option<Flag>) -> Result<()> {
- MaildirType::save_to_mailbox(self.mailboxes[&mailbox_hash].fs_path.clone(), bytes, flags)
+ fn save(
+ &self,
+ bytes: Vec<u8>,
+ mailbox_hash: MailboxHash,
+ flags: Option<Flag>,
+ ) -> ResultFuture<()> {
+ let path = self.mailboxes[&mailbox_hash].fs_path.clone();
+ Ok(Box::pin(async move {
+ MaildirType::save_to_mailbox(path, bytes, flags)
+ }))
}
- fn as_any(&self) -> &dyn::std::any::Any {
+ fn as_any(&self) -> &dyn ::std::any::Any {
self
}
fn create_mailbox(
&mut self,
new_path: String,
- ) -> Result<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
+ ) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
let mut path = self.path.clone();
path.push(&new_path);
if !path.starts_with(&self.path) {
@@ -720,21 +736,30 @@ impl MailBackend for MaildirType {
};
self.mailboxes.insert(mailbox_hash, new_mailbox);
- Ok((mailbox_hash, self.mailboxes()?))
+ let ret = Ok((mailbox_hash, self.mailboxes()?));
+ Ok(Box::pin(async { ret }))
}
fn delete_mailbox(
&mut self,
_mailbox_hash: MailboxHash,
- ) -> Result<HashMap<MailboxHash, Mailbox>> {
+ ) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
Err(MeliError::new("Unimplemented."))
}
- fn set_mailbox_subscription(&mut self, _mailbox_hash: MailboxHash, _val: bool) -> Result<()> {
+ fn set_mailbox_subscription(
+ &mut self,
+ _mailbox_hash: MailboxHash,
+ _val: bool,
+ ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
- fn rename_mailbox(&mut self, _mailbox_hash: MailboxHash, _new_path: String) -> Result<Mailbox> {
+ fn rename_mailbox(
+ &mut self,
+ _mailbox_hash: MailboxHash,
+ _new_path: String,
+ ) -> ResultFuture<Mailbox> {
Err(MeliError::new("Unimplemented."))
}
@@ -742,7 +767,7 @@ impl MailBackend for MaildirType {
&mut self,
_mailbox_hash: MailboxHash,
_val: crate::backends::MailboxPermissions,
- ) -> Result<()> {
+ ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
}
@@ -1084,7 +1109,7 @@ impl MaildirType {
w.build(handle)
}
- pub fn save_to_mailbox(mut path: PathBuf, bytes: &[u8], flags: Option<Flag>) -> Result<()> {
+ pub fn save_to_mailbox(mut path: PathBuf, bytes: Vec<u8>, flags: Option<Flag>) -> Result<()> {
for d in &["cur", "new", "tmp"] {
path.push(d);
if !path.is_dir() {
@@ -1149,7 +1174,7 @@ impl MaildirType {
file.set_permissions(permissions)?;
let mut writer = io::BufWriter::new(file);
- writer.write_all(bytes).unwrap();
+ writer.write_all(&bytes).unwrap();
return Ok(());
}
diff --git a/melib/src/backends/mbox.rs b/melib/src/backends/mbox.rs
index b5b26f64..4239c0f5 100644
--- a/melib/src/backends/mbox.rs
+++ b/melib/src/backends/mbox.rs
@@ -902,7 +902,12 @@ impl MailBackend for MboxType {
)))
}
- fn save(&self, _bytes: &[u8], _mailbox_hash: MailboxHash, _flags: Option<Flag>) -> Result<()> {
+ fn save(
+ &self,
+ _bytes: Vec<u8>,
+ _mailbox_hash: MailboxHash,
+ _flags: Option<Flag>,
+ ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
diff --git a/melib/src/backends/notmuch.rs b/melib/src/backends/notmuch.rs
index b8e4d701..fb755ec0 100644
--- a/melib/src/backends/notmuch.rs
+++ b/melib/src/backends/notmuch.rs
@@ -611,13 +611,19 @@ impl MailBackend for NotmuchDb {
}))
}
- fn save(&self, bytes: &[u8], _mailbox_hash: MailboxHash, flags: Option<Flag>) -> Result<()> {
+ fn save(
+ &self,
+ bytes: Vec<u8>,
+ _mailbox_hash: MailboxHash,
+ flags: Option<Flag>,
+ ) -> ResultFuture<()> {
let path = self
.save_messages_to
.as_ref()
.unwrap_or(&self.path)
.to_path_buf();
- MaildirType::save_to_mailbox(path, bytes, flags)
+ MaildirType::save_to_mailbox(path, bytes, flags)?;
+ Ok(Box::pin(async { Ok(()) }))
}
fn as_any(&self) -> &dyn ::std::any::Any {
diff --git a/src/components/mail/listing.rs b/src/components/mail/listing.rs
index afead265..f27b800e 100644
--- a/src/components/mail/listing.rs
+++ b/src/components/mail/listing.rs
@@ -356,7 +356,13 @@ pub trait ListingTrait: Component {
fn set_coordinates(&mut self, _: (usize, MailboxHash));
fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context);
fn highlight_line(&mut self, grid: &mut CellBuffer, area: Area, idx: usize, context: &Context);
- fn filter(&mut self, _filter_term: &str, _context: &Context) {}
+ fn filter(
+ &mut self,
+ _filter_term: String,
+ _results: Result<SmallVec<[EnvelopeHash; 512]>>,
+ _context: &Context,
+ ) {
+ }
fn set_movement(&mut self, mvm: PageMovement);
}
diff --git a/src/components/mail/listing/compact.rs b/src/components/mail/listing/compact.rs
index c4f48252..6543d97e 100644
--- a/src/components/mail/listing/compact.rs
+++ b/src/components/mail/listing/compact.rs
@@ -22,6 +22,7 @@
use super::EntryStrings;<