diff options
Diffstat (limited to 'src/imap/selectors.rs')
-rw-r--r-- | src/imap/selectors.rs | 103 |
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()) + } +} + |