From 6e798b90f590e21bb68535f0431fc547e5e2390c Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Tue, 9 Jan 2024 17:40:23 +0100 Subject: prepare condstore --- src/imap/command/examined.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/imap/command/examined.rs') diff --git a/src/imap/command/examined.rs b/src/imap/command/examined.rs index 3dd11e2..4767340 100644 --- a/src/imap/command/examined.rs +++ b/src/imap/command/examined.rs @@ -127,7 +127,7 @@ impl<'a> ExaminedContext<'a> { } pub async fn noop(self) -> Result<(Response<'static>, flow::Transition)> { - self.mailbox.0.mailbox.force_sync().await?; + self.mailbox.internal.mailbox.force_sync().await?; let updates = self.mailbox.update().await?; Ok(( -- cgit v1.2.3 From f4cbf665496640f4ac7cf4ac63ab2beced674978 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Wed, 10 Jan 2024 18:38:21 +0100 Subject: Fecth MODSEQ now enables the CONDSTORE capability --- src/imap/command/examined.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'src/imap/command/examined.rs') diff --git a/src/imap/command/examined.rs b/src/imap/command/examined.rs index 4767340..ef5cecc 100644 --- a/src/imap/command/examined.rs +++ b/src/imap/command/examined.rs @@ -91,14 +91,19 @@ impl<'a> ExaminedContext<'a> { uid: &bool, ) -> Result<(Response<'static>, flow::Transition)> { match self.mailbox.fetch(sequence_set, attributes, uid).await { - Ok(resp) => Ok(( - Response::build() - .to_req(self.req) - .message("FETCH completed") - .set_body(resp) - .ok()?, - flow::Transition::None, - )), + Ok((resp, enable_condstore)) => { + if enable_condstore { + self.client_capabilities.enable_condstore(); + } + Ok(( + Response::build() + .to_req(self.req) + .message("FETCH completed") + .set_body(resp) + .ok()?, + flow::Transition::None, + )) + }, Err(e) => Ok(( Response::build() .to_req(self.req) -- cgit v1.2.3 From fbf2e9aa9670c991f5384350b2c78ad38dc3baf8 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 11 Jan 2024 11:48:02 +0100 Subject: Enable CONDSTORE if SEARCH MODSEQ is queried --- src/imap/command/examined.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/imap/command/examined.rs') diff --git a/src/imap/command/examined.rs b/src/imap/command/examined.rs index ef5cecc..bb05250 100644 --- a/src/imap/command/examined.rs +++ b/src/imap/command/examined.rs @@ -120,7 +120,10 @@ impl<'a> ExaminedContext<'a> { criteria: &SearchKey<'a>, uid: &bool, ) -> Result<(Response<'static>, flow::Transition)> { - let found = self.mailbox.search(charset, criteria, *uid).await?; + let (found, enable_condstore) = self.mailbox.search(charset, criteria, *uid).await?; + if enable_condstore { + self.client_capabilities.enable_condstore(); + } Ok(( Response::build() .to_req(self.req) -- cgit v1.2.3 From 60a166185a034019d9e55136ee4417386ff57703 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 11 Jan 2024 16:55:37 +0100 Subject: Fetch and store modifiers are parsed --- src/imap/command/examined.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/imap/command/examined.rs') diff --git a/src/imap/command/examined.rs b/src/imap/command/examined.rs index bb05250..a8077e3 100644 --- a/src/imap/command/examined.rs +++ b/src/imap/command/examined.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use anyhow::Result; -use imap_codec::imap_types::command::{Command, CommandBody}; +use imap_codec::imap_types::command::{Command, CommandBody, FetchModifier}; use imap_codec::imap_types::core::Charset; use imap_codec::imap_types::fetch::MacroOrMessageDataItemNames; use imap_codec::imap_types::search::SearchKey; @@ -37,8 +37,9 @@ pub async fn dispatch(ctx: ExaminedContext<'_>) -> Result<(Response<'static>, fl CommandBody::Fetch { sequence_set, macro_or_item_names, + modifiers, uid, - } => ctx.fetch(sequence_set, macro_or_item_names, uid).await, + } => ctx.fetch(sequence_set, macro_or_item_names, modifiers, uid).await, CommandBody::Search { charset, criteria, @@ -88,6 +89,7 @@ impl<'a> ExaminedContext<'a> { self, sequence_set: &SequenceSet, attributes: &'a MacroOrMessageDataItemNames<'static>, + modifiers: &[FetchModifier], uid: &bool, ) -> Result<(Response<'static>, flow::Transition)> { match self.mailbox.fetch(sequence_set, attributes, uid).await { -- cgit v1.2.3 From d24eb9918e3ab0c69af05c8cb92424ecaba903f3 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 11 Jan 2024 17:13:59 +0100 Subject: Enable CONDSTORE on STORE/FETCH modifier --- src/imap/command/examined.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/imap/command/examined.rs') diff --git a/src/imap/command/examined.rs b/src/imap/command/examined.rs index a8077e3..cdebc6d 100644 --- a/src/imap/command/examined.rs +++ b/src/imap/command/examined.rs @@ -7,6 +7,7 @@ use imap_codec::imap_types::fetch::MacroOrMessageDataItemNames; use imap_codec::imap_types::search::SearchKey; use imap_codec::imap_types::sequence::SequenceSet; +use crate::imap::attributes::AttributesProxy; use crate::imap::capability::{ClientCapability, ServerCapability}; use crate::imap::command::{anystate, authenticated}; use crate::imap::flow; @@ -92,11 +93,15 @@ impl<'a> ExaminedContext<'a> { modifiers: &[FetchModifier], uid: &bool, ) -> Result<(Response<'static>, flow::Transition)> { - match self.mailbox.fetch(sequence_set, attributes, uid).await { - Ok((resp, enable_condstore)) => { - if enable_condstore { - self.client_capabilities.enable_condstore(); - } + let ap = AttributesProxy::new(attributes, *uid); + + match self.mailbox.fetch(sequence_set, &ap, uid).await { + Ok(resp) => { + // Capabilities enabling logic only on successful command + // (according to my understanding of the spec) + self.client_capabilities.attributes_enable(&ap); + self.client_capabilities.fetch_modifiers_enable(modifiers); + Ok(( Response::build() .to_req(self.req) -- cgit v1.2.3 From 3c7186ab5ac5a66f782a038d937b6679780df458 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 11 Jan 2024 23:02:03 +0100 Subject: Finalize implementation of CONDSTORE --- src/imap/command/examined.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/imap/command/examined.rs') diff --git a/src/imap/command/examined.rs b/src/imap/command/examined.rs index cdebc6d..9fc0990 100644 --- a/src/imap/command/examined.rs +++ b/src/imap/command/examined.rs @@ -1,4 +1,5 @@ use std::sync::Arc; +use std::num::NonZeroU64; use anyhow::Result; use imap_codec::imap_types::command::{Command, CommandBody, FetchModifier}; @@ -11,7 +12,7 @@ use crate::imap::attributes::AttributesProxy; use crate::imap::capability::{ClientCapability, ServerCapability}; use crate::imap::command::{anystate, authenticated}; use crate::imap::flow; -use crate::imap::mailbox_view::MailboxView; +use crate::imap::mailbox_view::{MailboxView, UpdateParameters}; use crate::imap::response::Response; use crate::mail::user::User; @@ -93,9 +94,15 @@ impl<'a> ExaminedContext<'a> { modifiers: &[FetchModifier], uid: &bool, ) -> Result<(Response<'static>, flow::Transition)> { - let ap = AttributesProxy::new(attributes, *uid); + let ap = AttributesProxy::new(attributes, modifiers, *uid); + let mut changed_since: Option = None; + modifiers.iter().for_each(|m| match m { + FetchModifier::ChangedSince(val) => { + changed_since = Some(*val); + }, + }); - match self.mailbox.fetch(sequence_set, &ap, uid).await { + match self.mailbox.fetch(sequence_set, &ap, changed_since, uid).await { Ok(resp) => { // Capabilities enabling logic only on successful command // (according to my understanding of the spec) @@ -144,7 +151,7 @@ impl<'a> ExaminedContext<'a> { pub async fn noop(self) -> Result<(Response<'static>, flow::Transition)> { self.mailbox.internal.mailbox.force_sync().await?; - let updates = self.mailbox.update().await?; + let updates = self.mailbox.update(UpdateParameters::default()).await?; Ok(( Response::build() .to_req(self.req) -- cgit v1.2.3