"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)> {
|
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(
|
async fn store(
|
||||||
|
|
|
@ -169,29 +169,7 @@ impl MailboxView {
|
||||||
self.mailbox.del_flags(*uuid, &flags[..]).await?;
|
self.mailbox.del_flags(*uuid, &flags[..]).await?;
|
||||||
}
|
}
|
||||||
StoreType::Replace => {
|
StoreType::Replace => {
|
||||||
let old_flags = &self
|
self.mailbox.set_flags(*uuid, &flags[..]).await?;
|
||||||
.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?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +177,10 @@ impl MailboxView {
|
||||||
self.update().await
|
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
|
/// Looks up state changes in the mailbox and produces a set of IMAP
|
||||||
/// responses describing the new state.
|
/// responses describing the new state.
|
||||||
pub async fn fetch(
|
pub async fn fetch(
|
||||||
|
|
|
@ -95,6 +95,11 @@ impl Mailbox {
|
||||||
self.mbox.write().await.del_flags(id, flags).await
|
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
|
/// Insert an email into the mailbox
|
||||||
pub async fn append<'a>(
|
pub async fn append<'a>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -265,6 +270,11 @@ impl MailboxInternal {
|
||||||
self.uid_index.push(del_flag_op).await
|
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(
|
async fn append(
|
||||||
&mut self,
|
&mut self,
|
||||||
mail: IMF<'_>,
|
mail: IMF<'_>,
|
||||||
|
|
|
@ -36,6 +36,7 @@ pub enum UidIndexOp {
|
||||||
MailDel(UniqueIdent),
|
MailDel(UniqueIdent),
|
||||||
FlagAdd(UniqueIdent, Vec<Flag>),
|
FlagAdd(UniqueIdent, Vec<Flag>),
|
||||||
FlagDel(UniqueIdent, Vec<Flag>),
|
FlagDel(UniqueIdent, Vec<Flag>),
|
||||||
|
FlagSet(UniqueIdent, Vec<Flag>),
|
||||||
BumpUidvalidity(u32),
|
BumpUidvalidity(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +61,11 @@ impl UidIndex {
|
||||||
UidIndexOp::FlagDel(ident, flags)
|
UidIndexOp::FlagDel(ident, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn op_flag_set(&self, ident: UniqueIdent, flags: Vec<Flag>) -> UidIndexOp {
|
||||||
|
UidIndexOp::FlagSet(ident, flags)
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn op_bump_uidvalidity(&self, count: u32) -> UidIndexOp {
|
pub fn op_bump_uidvalidity(&self, count: u32) -> UidIndexOp {
|
||||||
UidIndexOp::BumpUidvalidity(count)
|
UidIndexOp::BumpUidvalidity(count)
|
||||||
|
@ -162,6 +168,24 @@ impl BayouState for UidIndex {
|
||||||
new.idx_by_flag.remove(*uid, rm_flags);
|
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) => {
|
UidIndexOp::BumpUidvalidity(count) => {
|
||||||
new.uidvalidity = ImapUidvalidity::new(new.uidvalidity.get() + *count)
|
new.uidvalidity = ImapUidvalidity::new(new.uidvalidity.get() + *count)
|
||||||
.unwrap_or(ImapUidvalidity::new(u32::MAX).unwrap());
|
.unwrap_or(ImapUidvalidity::new(u32::MAX).unwrap());
|
||||||
|
|
Loading…
Reference in a new issue