aboutsummaryrefslogtreecommitdiff
path: root/src/imap/command/selected.rs
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2024-01-11 23:02:03 +0100
committerQuentin Dufour <quentin@deuxfleurs.fr>2024-01-11 23:02:03 +0100
commit3c7186ab5ac5a66f782a038d937b6679780df458 (patch)
treeee83fb3040ef077d36d807b0134c3141a0ea1d01 /src/imap/command/selected.rs
parentd24eb9918e3ab0c69af05c8cb92424ecaba903f3 (diff)
downloadaerogramme-3c7186ab5ac5a66f782a038d937b6679780df458.tar.gz
aerogramme-3c7186ab5ac5a66f782a038d937b6679780df458.zip
Finalize implementation of CONDSTORE
Diffstat (limited to 'src/imap/command/selected.rs')
-rw-r--r--src/imap/command/selected.rs28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/imap/command/selected.rs b/src/imap/command/selected.rs
index d7aa94f..d694fd1 100644
--- a/src/imap/command/selected.rs
+++ b/src/imap/command/selected.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, StoreModifier};
@@ -13,7 +14,7 @@ use imap_codec::imap_types::sequence::SequenceSet;
use crate::imap::capability::{ClientCapability, ServerCapability};
use crate::imap::command::{anystate, authenticated, MailboxName};
use crate::imap::flow;
-use crate::imap::mailbox_view::MailboxView;
+use crate::imap::mailbox_view::{MailboxView, UpdateParameters};
use crate::imap::response::Response;
use crate::imap::attributes::AttributesProxy;
use crate::mail::user::User;
@@ -118,9 +119,15 @@ impl<'a> SelectedContext<'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<NonZeroU64> = 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)
@@ -170,7 +177,7 @@ impl<'a> SelectedContext<'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)
@@ -204,10 +211,18 @@ impl<'a> SelectedContext<'a> {
modifiers: &[StoreModifier],
uid: &bool,
) -> Result<(Response<'static>, flow::Transition)> {
- let data = self
+ let mut unchanged_since: Option<NonZeroU64> = None;
+ modifiers.iter().for_each(|m| match m {
+ StoreModifier::UnchangedSince(val) => {
+ unchanged_since = Some(*val);
+ },
+ });
+
+ let (data, modified) = self
.mailbox
- .store(sequence_set, kind, response, flags, uid)
+ .store(sequence_set, kind, response, flags, unchanged_since, uid)
.await?;
+ let modified_str = format!("MODIFIED {}", modified.into_iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","));
self.client_capabilities.store_modifiers_enable(modifiers);
@@ -215,6 +230,7 @@ impl<'a> SelectedContext<'a> {
Response::build()
.to_req(self.req)
.message("STORE completed")
+ .code(Code::Other(CodeOther::unvalidated(modified_str.into_bytes())))
.set_body(data)
.ok()?,
flow::Transition::None,