melib: Implement delete_messages for IMAP, Maildir

jmap-eventsource
Manos Pitsidianakis 2020-10-13 13:57:04 +03:00
parent 19891a3042
commit cd68008e67
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
8 changed files with 94 additions and 26 deletions

View File

@ -335,15 +335,11 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
) -> ResultFuture<()>;
fn delete_messages(
&self,
_env_hashes: EnvelopeHashBatch,
_mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
fn delete(&self, _env_hash: EnvelopeHash, _mailbox_hash: MailboxHash) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
&mut self,
env_hashes: EnvelopeHashBatch,
mailbox_hash: MailboxHash,
) -> ResultFuture<()>;
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
None
}

View File

@ -807,6 +807,29 @@ impl MailBackend for ImapType {
}))
}
fn delete_messages(
&mut self,
env_hashes: EnvelopeHashBatch,
mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
let flag_future = self.set_flags(
env_hashes,
mailbox_hash,
smallvec::smallvec![(Ok(Flag::TRASHED), true)],
)?;
let connection = self.connection.clone();
Ok(Box::pin(async move {
flag_future.await?;
let mut response = Vec::with_capacity(8 * 1024);
let mut conn = connection.lock().await;
conn.send_command("EXPUNGE".as_bytes()).await?;
conn.read_response(&mut response, RequiredResponses::empty())
.await?;
debug!("EXPUNGE response: {}", &String::from_utf8_lossy(&response));
Ok(())
}))
}
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
Some(self.uid_store.tag_index.clone())
}

View File

@ -788,6 +788,14 @@ impl MailBackend for JmapType {
Ok(())
}))
}
fn delete_messages(
&mut self,
_env_hashes: EnvelopeHashBatch,
_mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
}
impl JmapType {

View File

@ -913,6 +913,37 @@ impl MailBackend for MaildirType {
}))
}
fn delete_messages(
&mut self,
env_hashes: EnvelopeHashBatch,
mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
let hash_index = self.hash_indexes.clone();
Ok(Box::pin(async move {
let mut hash_indexes_lck = hash_index.lock().unwrap();
let hash_index = hash_indexes_lck.entry(mailbox_hash).or_default();
for env_hash in env_hashes.iter() {
let _path = {
if !hash_index.contains_key(&env_hash) {
continue;
}
if let Some(modif) = &hash_index[&env_hash].modified {
match modif {
PathMod::Path(ref path) => path.clone(),
PathMod::Hash(hash) => hash_index[&hash].to_path_buf(),
}
} else {
hash_index[&env_hash].to_path_buf()
}
};
fs::remove_file(&_path)?;
}
Ok(())
}))
}
fn copy_messages(
&mut self,
env_hashes: EnvelopeHashBatch,

View File

@ -1012,6 +1012,14 @@ impl MailBackend for MboxType {
Err(MeliError::new("Unimplemented."))
}
fn delete_messages(
&mut self,
_env_hashes: EnvelopeHashBatch,
_mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
fn save(
&self,
_bytes: Vec<u8>,

View File

@ -278,7 +278,7 @@ impl MailBackend for NntpType {
_mailbox_hash: MailboxHash,
_flags: Option<Flag>,
) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
Err(MeliError::new("NNTP doesn't support saving."))
}
fn copy_messages(
@ -288,7 +288,7 @@ impl MailBackend for NntpType {
_destination_mailbox_hash: MailboxHash,
_move_: bool,
) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
Err(MeliError::new("NNTP doesn't support copying/moving."))
}
fn set_flags(
@ -297,7 +297,15 @@ impl MailBackend for NntpType {
_mailbox_hash: MailboxHash,
_flags: SmallVec<[(std::result::Result<Flag, String>, bool); 8]>,
) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
Err(MeliError::new("NNTP doesn't support flags."))
}
fn delete_messages(
&mut self,
_env_hashes: EnvelopeHashBatch,
_mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
Err(MeliError::new("NNTP doesn't support deletion."))
}
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {

View File

@ -802,6 +802,14 @@ impl MailBackend for NotmuchDb {
}))
}
fn delete_messages(
&mut self,
_env_hashes: EnvelopeHashBatch,
_mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
fn search(
&self,
melib_query: crate::search::Query,

View File

@ -1378,20 +1378,6 @@ impl Account {
}
}
pub fn delete(
&mut self,
env_hash: EnvelopeHash,
mailbox_hash: MailboxHash,
) -> ResultFuture<()> {
if self.settings.account.read_only() {
return Err(MeliError::new(format!(
"Account {} is read-only.",
self.name.as_str()
)));
}
self.backend.write().unwrap().delete(env_hash, mailbox_hash)
}
pub fn contains_key(&self, h: EnvelopeHash) -> bool {
self.collection.contains_key(&h)
}