diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-06-30 11:40:26 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-07-06 15:26:00 +0300 |
commit | e06308fed26e0730b2f8a15880a371cd38bfdf20 (patch) | |
tree | 47465e3d5a8098bc6f391ce1acfc3b5e69c8a150 | |
parent | 03522c0298a50cdb943664f2786f6a58eebce828 (diff) |
MailBackend: change more methods to Futures
-rw-r--r-- | melib/src/backends.rs | 53 | ||||
-rw-r--r-- | melib/src/backends/imap.rs | 66 | ||||
-rw-r--r-- | melib/src/backends/imap/protocol_parser.rs | 1 | ||||
-rw-r--r-- | melib/src/backends/imap_async.rs | 110 | ||||
-rw-r--r-- | melib/src/backends/imap_async/connection.rs | 1 | ||||
-rw-r--r-- | melib/src/backends/imap_async/protocol_parser.rs | 1 | ||||
-rw-r--r-- | melib/src/backends/jmap.rs | 13 | ||||
-rw-r--r-- | melib/src/backends/maildir/backend.rs | 47 | ||||
-rw-r--r-- | melib/src/backends/mbox.rs | 7 | ||||
-rw-r--r-- | melib/src/backends/notmuch.rs | 10 | ||||
-rw-r--r-- | src/components/mail/listing.rs | 8 | ||||
-rw-r--r-- | src/components/mail/listing/compact.rs | 59 | ||||
-rw-r--r-- | src/components/mail/listing/conversations.rs | 169 | ||||
-rw-r--r-- | src/components/mail/listing/offline.rs | 2 | ||||
-rw-r--r-- | src/components/mail/listing/plain.rs | 147 | ||||
-rw-r--r-- | src/components/utilities.rs | 37 | ||||
-rw-r--r-- | src/components/utilities/widgets.rs | 23 | ||||
-rw-r--r-- | src/conf/accounts.rs | 232 | ||||
-rw-r--r-- | src/plugins/backend.rs | 9 | ||||
-rw-r--r-- | src/types.rs | 2 | ||||
-rw-r--r-- | src/unix.rs | 6 |
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;< |