filter expunge
This commit is contained in:
parent
0cc38571f4
commit
c2a518a997
3 changed files with 25 additions and 12 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1807,7 +1807,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "imap-codec"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/superboum/imap-codec?branch=custom/aerogramme#b0a80c4826f3d8bf2d2e69f68443c261e62bb40f"
|
||||
source = "git+https://github.com/superboum/imap-codec?branch=custom/aerogramme#0f27fe2f10d16c96e0be18914fdbeda9df545beb"
|
||||
dependencies = [
|
||||
"abnf-core",
|
||||
"base64 0.21.5",
|
||||
|
@ -1834,7 +1834,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "imap-types"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/superboum/imap-codec?branch=custom/aerogramme#b0a80c4826f3d8bf2d2e69f68443c261e62bb40f"
|
||||
source = "git+https://github.com/superboum/imap-codec?branch=custom/aerogramme#0f27fe2f10d16c96e0be18914fdbeda9df545beb"
|
||||
dependencies = [
|
||||
"base64 0.21.5",
|
||||
"bounded-static",
|
||||
|
|
|
@ -59,7 +59,10 @@ pub async fn dispatch<'a>(
|
|||
criteria,
|
||||
uid,
|
||||
} => ctx.search(charset, criteria, uid).await,
|
||||
CommandBody::Expunge => ctx.expunge().await,
|
||||
CommandBody::Expunge {
|
||||
// UIDPLUS (rfc4315)
|
||||
uid_sequence_set,
|
||||
} => ctx.expunge(uid_sequence_set).await,
|
||||
CommandBody::Store {
|
||||
sequence_set,
|
||||
kind,
|
||||
|
@ -114,7 +117,7 @@ impl<'a> SelectedContext<'a> {
|
|||
// We expunge messages,
|
||||
// but we don't send the untagged EXPUNGE responses
|
||||
let tag = self.req.tag.clone();
|
||||
self.expunge().await?;
|
||||
self.expunge(&None).await?;
|
||||
Ok((
|
||||
Response::build().tag(tag).message("CLOSE completed").ok()?,
|
||||
flow::Transition::Unselect,
|
||||
|
@ -223,13 +226,13 @@ impl<'a> SelectedContext<'a> {
|
|||
))
|
||||
}
|
||||
|
||||
async fn expunge(self) -> Result<(Response<'static>, flow::Transition)> {
|
||||
async fn expunge(self, uid_sequence_set: &Option<SequenceSet>) -> Result<(Response<'static>, flow::Transition)> {
|
||||
if let Some(failed) = self.fail_read_only() {
|
||||
return Ok((failed, flow::Transition::None));
|
||||
}
|
||||
|
||||
let tag = self.req.tag.clone();
|
||||
let data = self.mailbox.expunge().await?;
|
||||
let data = self.mailbox.expunge(uid_sequence_set).await?;
|
||||
|
||||
Ok((
|
||||
Response::build()
|
||||
|
|
|
@ -237,16 +237,26 @@ impl MailboxView {
|
|||
self.update(UpdateParameters::default()).await
|
||||
}
|
||||
|
||||
pub async fn expunge(&mut self) -> Result<Vec<Body<'static>>> {
|
||||
pub async fn expunge(&mut self, maybe_seq_set: &Option<SequenceSet>) -> Result<Vec<Body<'static>>> {
|
||||
// Get a recent view to apply our change
|
||||
self.internal.sync().await?;
|
||||
let state = self.internal.peek().await;
|
||||
let idx = Index::new(&state)?;
|
||||
|
||||
// Build a default sequence set for the default case
|
||||
use imap_codec::imap_types::sequence::{Sequence, SeqOrUid};
|
||||
let seq = match maybe_seq_set {
|
||||
Some(s) => s.clone(),
|
||||
None => SequenceSet(vec![Sequence::Range(SeqOrUid::Value(NonZeroU32::MIN), SeqOrUid::Asterisk)].try_into().unwrap()),
|
||||
};
|
||||
|
||||
|
||||
let deleted_flag = Flag::Deleted.to_string();
|
||||
let msgs = state
|
||||
.table
|
||||
.iter()
|
||||
.filter(|(_uuid, (_uid, _modseq, flags))| flags.iter().any(|x| *x == deleted_flag))
|
||||
.map(|(uuid, _)| *uuid);
|
||||
let msgs = idx
|
||||
.fetch_on_uid(&seq)
|
||||
.into_iter()
|
||||
.filter(|midx| midx.flags.iter().any(|x| *x == deleted_flag))
|
||||
.map(|midx| midx.uuid);
|
||||
|
||||
for msg in msgs {
|
||||
self.internal.mailbox.delete(msg).await?;
|
||||
|
|
Loading…
Reference in a new issue