"set flags" as a bayou op
This commit is contained in:
parent
7959adb8e9
commit
a1ca6d9def
4 changed files with 45 additions and 24 deletions
|
@ -62,7 +62,12 @@ impl<'a> SelectedContext<'a> {
|
|||
}
|
||||
|
||||
async fn expunge(self) -> Result<(Response, flow::Transition)> {
|
||||
Ok((Response::bad("Not implemented")?, flow::Transition::None))
|
||||
let data = self.mailbox.expunge().await?;
|
||||
|
||||
Ok((
|
||||
Response::ok("EXPUNGE completed")?.with_body(data),
|
||||
flow::Transition::None,
|
||||
))
|
||||
}
|
||||
|
||||
async fn store(
|
||||
|
|
|
@ -169,29 +169,7 @@ impl MailboxView {
|
|||
self.mailbox.del_flags(*uuid, &flags[..]).await?;
|
||||
}
|
||||
StoreType::Replace => {
|
||||
let old_flags = &self
|
||||
.known_state
|
||||
.table
|
||||
.get(uuid)
|
||||
.ok_or(anyhow!(
|
||||
"Missing message: {} (UID {}, UUID {})",
|
||||
i,
|
||||
uid,
|
||||
uuid
|
||||
))?
|
||||
.1;
|
||||
let to_remove = old_flags
|
||||
.iter()
|
||||
.filter(|x| !flags.contains(&x))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
let to_add = flags
|
||||
.iter()
|
||||
.filter(|x| !old_flags.contains(&x))
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
self.mailbox.add_flags(*uuid, &to_add[..]).await?;
|
||||
self.mailbox.del_flags(*uuid, &to_remove[..]).await?;
|
||||
self.mailbox.set_flags(*uuid, &flags[..]).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,6 +177,10 @@ impl MailboxView {
|
|||
self.update().await
|
||||
}
|
||||
|
||||
pub async fn expunge(&mut self) -> Result<Vec<Body>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Looks up state changes in the mailbox and produces a set of IMAP
|
||||
/// responses describing the new state.
|
||||
pub async fn fetch(
|
||||
|
|
|
@ -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<'_>,
|
||||
|
|
|
@ -36,6 +36,7 @@ pub enum UidIndexOp {
|
|||
MailDel(UniqueIdent),
|
||||
FlagAdd(UniqueIdent, Vec<Flag>),
|
||||
FlagDel(UniqueIdent, Vec<Flag>),
|
||||
FlagSet(UniqueIdent, Vec<Flag>),
|
||||
BumpUidvalidity(u32),
|
||||
}
|
||||
|
||||
|
@ -60,6 +61,11 @@ impl UidIndex {
|
|||
UidIndexOp::FlagDel(ident, flags)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn op_flag_set(&self, ident: UniqueIdent, flags: Vec<Flag>) -> 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<String>, Vec<String>) = existing_flags
|
||||
.iter()
|
||||
.cloned()
|
||||
.partition(|x| new_flags.contains(x));
|
||||
*existing_flags = keep_flags;
|
||||
let mut to_add: Vec<Flag> = 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());
|
||||
|
|
Loading…
Reference in a new issue