From a1ca6d9defc844fee52d966951701a57727050c7 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Wed, 13 Jul 2022 11:00:35 +0200 Subject: "set flags" as a bayou op --- src/mail/mailbox.rs | 10 ++++++++++ src/mail/uidindex.rs | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'src/mail') diff --git a/src/mail/mailbox.rs b/src/mail/mailbox.rs index 0e8af70..4b84cf2 100644 --- a/src/mail/mailbox.rs +++ b/src/mail/mailbox.rs @@ -95,6 +95,11 @@ impl Mailbox { self.mbox.write().await.del_flags(id, flags).await } + /// Define the new flags for this message + pub async fn set_flags<'a>(&self, id: UniqueIdent, flags: &[Flag]) -> Result<()> { + self.mbox.write().await.set_flags(id, flags).await + } + /// Insert an email into the mailbox pub async fn append<'a>( &self, @@ -265,6 +270,11 @@ impl MailboxInternal { self.uid_index.push(del_flag_op).await } + async fn set_flags(&mut self, ident: UniqueIdent, flags: &[Flag]) -> Result<()> { + let set_flag_op = self.uid_index.state().op_flag_set(ident, flags.to_vec()); + self.uid_index.push(set_flag_op).await + } + async fn append( &mut self, mail: IMF<'_>, diff --git a/src/mail/uidindex.rs b/src/mail/uidindex.rs index 6da08c1..3a3e252 100644 --- a/src/mail/uidindex.rs +++ b/src/mail/uidindex.rs @@ -36,6 +36,7 @@ pub enum UidIndexOp { MailDel(UniqueIdent), FlagAdd(UniqueIdent, Vec), FlagDel(UniqueIdent, Vec), + FlagSet(UniqueIdent, Vec), BumpUidvalidity(u32), } @@ -60,6 +61,11 @@ impl UidIndex { UidIndexOp::FlagDel(ident, flags) } + #[must_use] + pub fn op_flag_set(&self, ident: UniqueIdent, flags: Vec) -> UidIndexOp { + UidIndexOp::FlagSet(ident, flags) + } + #[must_use] pub fn op_bump_uidvalidity(&self, count: u32) -> UidIndexOp { UidIndexOp::BumpUidvalidity(count) @@ -162,6 +168,24 @@ impl BayouState for UidIndex { new.idx_by_flag.remove(*uid, rm_flags); } } + UidIndexOp::FlagSet(ident, new_flags) => { + if let Some((uid, existing_flags)) = new.table.get_mut(ident) { + // Remove flags from the source of trust and the cache + let (keep_flags, rm_flags): (Vec, Vec) = existing_flags + .iter() + .cloned() + .partition(|x| new_flags.contains(x)); + *existing_flags = keep_flags; + let mut to_add: Vec = new_flags + .iter() + .filter(|f| !existing_flags.contains(f)) + .cloned() + .collect(); + existing_flags.append(&mut to_add); + new.idx_by_flag.remove(*uid, &rm_flags); + new.idx_by_flag.insert(*uid, &to_add); + } + } UidIndexOp::BumpUidvalidity(count) => { new.uidvalidity = ImapUidvalidity::new(new.uidvalidity.get() + *count) .unwrap_or(ImapUidvalidity::new(u32::MAX).unwrap()); -- cgit v1.2.3