diff options
author | Quentin <quentin@dufour.io> | 2024-01-08 10:39:26 +0000 |
---|---|---|
committer | Quentin <quentin@dufour.io> | 2024-01-08 10:39:26 +0000 |
commit | d7788e29a8a64550e9b274001ff3fb9a7bf3473b (patch) | |
tree | e43a11753472f1917ce4aa6ddba24ae3a513bd50 /src/imap/mailbox_view.rs | |
parent | 152d5b7604337fe19a7aea7fc37b3d4615ca7393 (diff) | |
parent | 42a54b2c500294c594f3efdd25db28c18f5ac238 (diff) | |
download | aerogramme-d7788e29a8a64550e9b274001ff3fb9a7bf3473b.tar.gz aerogramme-d7788e29a8a64550e9b274001ff3fb9a7bf3473b.zip |
Merge pull request 'Implement search' (#61) from feat/search into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/aerogramme/pulls/61
Diffstat (limited to 'src/imap/mailbox_view.rs')
-rw-r--r-- | src/imap/mailbox_view.rs | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/imap/mailbox_view.rs b/src/imap/mailbox_view.rs index e4ffdcd..77fe7f7 100644 --- a/src/imap/mailbox_view.rs +++ b/src/imap/mailbox_view.rs @@ -146,7 +146,8 @@ impl MailboxView { let flags = flags.iter().map(|x| x.to_string()).collect::<Vec<_>>(); - let mails = self.index().fetch(sequence_set, *is_uid_store)?; + let idx = self.index()?; + let mails = idx.fetch(sequence_set, *is_uid_store)?; for mi in mails.iter() { match kind { StoreType::Add => { @@ -189,7 +190,8 @@ impl MailboxView { to: Arc<Mailbox>, is_uid_copy: &bool, ) -> Result<(ImapUidvalidity, Vec<(ImapUid, ImapUid)>)> { - let mails = self.index().fetch(sequence_set, *is_uid_copy)?; + let idx = self.index()?; + let mails = idx.fetch(sequence_set, *is_uid_copy)?; let mut new_uuids = vec![]; for mi in mails.iter() { @@ -216,7 +218,8 @@ impl MailboxView { to: Arc<Mailbox>, is_uid_copy: &bool, ) -> Result<(ImapUidvalidity, Vec<(ImapUid, ImapUid)>, Vec<Body<'static>>)> { - let mails = self.index().fetch(sequence_set, *is_uid_copy)?; + let idx = self.index()?; + let mails = idx.fetch(sequence_set, *is_uid_copy)?; for mi in mails.iter() { to.move_from(&self.0.mailbox, mi.uuid).await?; @@ -254,7 +257,8 @@ impl MailboxView { true => QueryScope::Full, _ => QueryScope::Partial, }; - let mail_idx_list = self.index().fetch(sequence_set, *is_uid_fetch)?; + let idx = self.index()?; + let mail_idx_list = idx.fetch(sequence_set, *is_uid_fetch)?; // [2/6] Fetch the emails let uuids = mail_idx_list @@ -316,29 +320,38 @@ impl MailboxView { let (seq_set, seq_type) = crit.to_sequence_set(); // 2. Get the selection - let selection = self.index().fetch(&seq_set, seq_type.is_uid())?; + let idx = self.index()?; + let selection = idx.fetch(&seq_set, seq_type.is_uid())?; // 3. Filter the selection based on the ID / UID / Flags + let (kept_idx, to_fetch) = crit.filter_on_idx(&selection); - // 4. If needed, filter the selection based on the metadata - let _need_meta = crit.need_meta(); + // 4. Fetch additional info about the emails + let query_scope = crit.query_scope(); + let uuids = to_fetch.iter().map(|midx| midx.uuid).collect::<Vec<_>>(); + let query_result = self.0.query(&uuids, query_scope).fetch().await?; // 5. If needed, filter the selection based on the body - let _need_body = crit.need_body(); + let kept_query = crit.filter_on_query(&to_fetch, &query_result)?; // 6. Format the result according to the client's taste: // either return UID or ID. + let final_selection = kept_idx.into_iter().chain(kept_query.into_iter()); let selection_fmt = match uid { - true => selection.into_iter().map(|in_idx| in_idx.uid).collect(), - _ => selection.into_iter().map(|in_idx| in_idx.i).collect(), + true => final_selection.map(|in_idx| in_idx.uid).collect(), + _ => final_selection.map(|in_idx| in_idx.i).collect(), }; Ok(vec![Body::Data(Data::Search(selection_fmt))]) } // ---- - fn index<'a>(&'a self) -> Index<'a> { - Index(&self.0.snapshot) + /// @FIXME index should be stored for longer than a single request + /// Instead they should be tied to the FrozenMailbox refresh + /// It's not trivial to refactor the code to do that, so we are doing + /// some useless computation for now... + fn index<'a>(&'a self) -> Result<Index<'a>> { + Index::new(&self.0.snapshot) } /// Produce an OK [UIDVALIDITY _] message corresponding to `known_state` @@ -513,7 +526,7 @@ mod tests { content: rfc822.to_vec(), }; - let mv = MailView::new(&qr, mail_in_idx)?; + let mv = MailView::new(&qr, &mail_in_idx)?; let (res_body, _seen) = mv.filter(&ap)?; let fattr = match res_body { |