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<()>; ) -> ResultFuture<()>;
fn delete_messages( fn delete_messages(
&self, &mut self,
_env_hashes: EnvelopeHashBatch, env_hashes: EnvelopeHashBatch,
_mailbox_hash: MailboxHash, mailbox_hash: MailboxHash,
) -> ResultFuture<()> { ) -> ResultFuture<()>;
Err(MeliError::new("Unimplemented."))
}
fn delete(&self, _env_hash: EnvelopeHash, _mailbox_hash: MailboxHash) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
}
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> { fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
None 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>>>> { fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
Some(self.uid_store.tag_index.clone()) Some(self.uid_store.tag_index.clone())
} }

View File

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

View File

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

View File

@ -278,7 +278,7 @@ impl MailBackend for NntpType {
_mailbox_hash: MailboxHash, _mailbox_hash: MailboxHash,
_flags: Option<Flag>, _flags: Option<Flag>,
) -> ResultFuture<()> { ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented.")) Err(MeliError::new("NNTP doesn't support saving."))
} }
fn copy_messages( fn copy_messages(
@ -288,7 +288,7 @@ impl MailBackend for NntpType {
_destination_mailbox_hash: MailboxHash, _destination_mailbox_hash: MailboxHash,
_move_: bool, _move_: bool,
) -> ResultFuture<()> { ) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented.")) Err(MeliError::new("NNTP doesn't support copying/moving."))
} }
fn set_flags( fn set_flags(
@ -297,7 +297,15 @@ impl MailBackend for NntpType {
_mailbox_hash: MailboxHash, _mailbox_hash: MailboxHash,
_flags: SmallVec<[(std::result::Result<Flag, String>, bool); 8]>, _flags: SmallVec<[(std::result::Result<Flag, String>, bool); 8]>,
) -> ResultFuture<()> { ) -> 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>>>> { 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( fn search(
&self, &self,
melib_query: crate::search::Query, 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 { pub fn contains_key(&self, h: EnvelopeHash) -> bool {
self.collection.contains_key(&h) self.collection.contains_key(&h)
} }