aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2024-01-11 11:48:02 +0100
committerQuentin Dufour <quentin@deuxfleurs.fr>2024-01-11 11:48:02 +0100
commitfbf2e9aa9670c991f5384350b2c78ad38dc3baf8 (patch)
tree51555e9c3371622fefd854c89ce887a8814fa0e1 /src
parent917c32ae0b6fa3161cebdfeec748b2db0bbc1c70 (diff)
downloadaerogramme-fbf2e9aa9670c991f5384350b2c78ad38dc3baf8.tar.gz
aerogramme-fbf2e9aa9670c991f5384350b2c78ad38dc3baf8.zip
Enable CONDSTORE if SEARCH MODSEQ is queried
Diffstat (limited to 'src')
-rw-r--r--src/imap/command/examined.rs5
-rw-r--r--src/imap/command/selected.rs5
-rw-r--r--src/imap/mailbox_view.rs7
-rw-r--r--src/imap/search.rs11
4 files changed, 24 insertions, 4 deletions
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)
diff --git a/src/imap/command/selected.rs b/src/imap/command/selected.rs
index 24e1f41..de59ed3 100644
--- a/src/imap/command/selected.rs
+++ b/src/imap/command/selected.rs
@@ -146,7 +146,10 @@ impl<'a> SelectedContext<'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)
diff --git a/src/imap/mailbox_view.rs b/src/imap/mailbox_view.rs
index 61beed5..ecdd745 100644
--- a/src/imap/mailbox_view.rs
+++ b/src/imap/mailbox_view.rs
@@ -325,7 +325,7 @@ impl MailboxView {
_charset: &Option<Charset<'a>>,
search_key: &SearchKey<'a>,
uid: bool,
- ) -> Result<Vec<Body<'static>>> {
+ ) -> Result<(Vec<Body<'static>>, bool)> {
// 1. Compute the subset of sequence identifiers we need to fetch
// based on the search query
let crit = search::Criteria(search_key);
@@ -354,7 +354,10 @@ impl MailboxView {
_ => final_selection.map(|in_idx| in_idx.i).collect(),
};
- Ok(vec![Body::Data(Data::Search(selection_fmt))])
+ // 7. Add the modseq entry if needed
+ let is_modseq = crit.is_modseq();
+
+ Ok((vec![Body::Data(Data::Search(selection_fmt))], is_modseq))
}
// ----
diff --git a/src/imap/search.rs b/src/imap/search.rs
index 12bad51..61cbad5 100644
--- a/src/imap/search.rs
+++ b/src/imap/search.rs
@@ -112,6 +112,17 @@ impl<'a> Criteria<'a> {
}
}
+ pub fn is_modseq(&self) -> bool {
+ use SearchKey::*;
+ match self.0 {
+ And(and_list) => and_list.as_ref().iter().any(|child| Criteria(child).is_modseq()),
+ Or(left, right) => Criteria(left).is_modseq() || Criteria(right).is_modseq(),
+ Not(child) => Criteria(child).is_modseq(),
+ ModSeq { .. } => true,
+ _ => false,
+ }
+ }
+
/// Returns emails that we now for sure we want to keep
/// but also a second list of emails we need to investigate further by
/// fetching some remote data