aboutsummaryrefslogtreecommitdiff
path: root/src/imap/selectors.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/imap/selectors.rs')
-rw-r--r--src/imap/selectors.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/imap/selectors.rs b/src/imap/selectors.rs
new file mode 100644
index 0000000..6b5372a
--- /dev/null
+++ b/src/imap/selectors.rs
@@ -0,0 +1,103 @@
+use std::iter::zip;
+
+use anyhow::{anyhow, Result};
+
+
+use crate::cryptoblob::Key;
+use crate::imap::mail_view::{MailView, FetchedMail};
+use crate::imap::mailbox_view::MailIdentifiers;
+use crate::mail::mailbox::MailMeta;
+use crate::mail::unique_ident::UniqueIdent;
+
+pub struct BodyIdentifier<'a> {
+ pub msg_uuid: &'a UniqueIdent,
+ pub msg_key: &'a Key,
+}
+
+
+#[derive(Default)]
+pub struct MailSelectionBuilder<'a> {
+ //attrs: AttributeProxy,
+ mail_count: usize,
+ need_body: bool,
+ mi: &'a [MailIdentifiers],
+ meta: &'a [MailMeta],
+ flags: &'a [&'a Vec<String>],
+ bodies: &'a [Vec<u8>],
+}
+
+impl<'a> MailSelectionBuilder<'a> {
+ pub fn new(need_body: bool, mail_count: usize) -> Self {
+ Self {
+ mail_count,
+ need_body,
+ ..MailSelectionBuilder::default()
+ }
+ }
+
+ pub fn with_mail_identifiers(&mut self, mi: &'a [MailIdentifiers]) -> &mut Self {
+ self.mi = mi;
+ self
+ }
+
+ pub fn with_metadata(&mut self, meta: &'a [MailMeta]) -> &mut Self {
+ self.meta = meta;
+ self
+ }
+
+ pub fn with_flags(&mut self, flags: &'a [&'a Vec<String>]) -> &mut Self {
+ self.flags = flags;
+ self
+ }
+
+ pub fn bodies_to_collect(&self) -> Vec<BodyIdentifier> {
+ if !self.need_body {
+ return vec![];
+ }
+ zip(self.mi, self.meta)
+ .map(|(mi, meta)| BodyIdentifier {
+ msg_uuid: &mi.uuid,
+ msg_key: &meta.message_key,
+ })
+ .collect::<Vec<_>>()
+ }
+
+ pub fn with_bodies(&mut self, rbodies: &'a [Vec<u8>]) -> &mut Self {
+ self.bodies = rbodies;
+ self
+ }
+
+ pub fn build(&self) -> Result<Vec<MailView<'a>>> {
+ let mut bodies = vec![];
+
+ if !self.need_body {
+ for m in self.meta.iter() {
+ let (_, hdrs) =
+ eml_codec::parse_imf(&m.headers).or(Err(anyhow!("Invalid mail headers")))?;
+ bodies.push(FetchedMail::Partial(hdrs));
+ }
+ } else {
+ for rb in self.bodies.iter() {
+ let (_, p) = eml_codec::parse_message(&rb).or(Err(anyhow!("Invalid mail body")))?;
+ bodies.push(FetchedMail::new_from_message(p));
+ }
+ }
+
+ if self.mi.len() != self.mail_count && self.meta.len() != self.mail_count
+ || self.flags.len() != self.mail_count
+ || bodies.len() != self.mail_count
+ {
+ return Err(anyhow!("Can't build a mail view selection as parts were not correctly registered into the builder."));
+ }
+
+ Ok(zip(self.mi, zip(self.meta, zip(self.flags, bodies)))
+ .map(|(ids, (meta, (flags, content)))| MailView {
+ ids,
+ meta,
+ flags,
+ content,
+ })
+ .collect())
+ }
+}
+