aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2023-09-28 11:57:46 +0200
committerQuentin Dufour <quentin@deuxfleurs.fr>2023-09-28 11:57:46 +0200
commit2270aaa96369d155cd3dfacf54487f974e1ef72b (patch)
treefe86600a57ecce2052dad2c9be10ee9234d5dd4f
parent1fb9970502ed654d99ab41dd8d1cb5c09ea91c02 (diff)
downloadaerogramme-2270aaa96369d155cd3dfacf54487f974e1ef72b.tar.gz
aerogramme-2270aaa96369d155cd3dfacf54487f974e1ef72b.zip
WIP
-rw-r--r--src/imap/mailbox_view.rs149
1 files changed, 123 insertions, 26 deletions
diff --git a/src/imap/mailbox_view.rs b/src/imap/mailbox_view.rs
index d04fabf..1b9337e 100644
--- a/src/imap/mailbox_view.rs
+++ b/src/imap/mailbox_view.rs
@@ -59,6 +59,96 @@ impl<'a> FetchedMail<'a> {
}
}
+pub struct MailIdentifiers {
+ i: NonZeroU32,
+ uid: ImapUid,
+ uuid: UniqueIdent,
+}
+
+pub struct MailView<'a> {
+ ids: MailIdentifiers,
+ meta: MailMeta,
+ flags: Vec<Flag>,
+ content: FetchedMail<'a>,
+}
+
+pub struct AttributesProxy {
+ attrs: FetchAttributes
+}
+impl AttributeProxy {
+ fn new(attrs: &MacroOrFetchAttributes, is_uid_fetch: bool) -> Self {
+ // Expand macros
+ let mut fetch_attrs = match attributes {
+ MacroOrFetchAttributes::Macro(m) => m.expand(),
+ MacroOrFetchAttributes::FetchAttributes(a) => a.clone(),
+ };
+
+ // Handle uids
+ if *is_uid_fetch && !fetch_attrs.contains(&FetchAttribute::Uid) {
+ fetch_attrs.push(FetchAttribute::Uid);
+ }
+
+ Self { attrs: fetch_attrs }
+ }
+
+ fn need_body(&self) -> bool {
+ self.attrs.iter().any(|x| {
+ matches!(
+ x,
+ FetchAttribute::Body
+ | FetchAttribute::BodyExt { .. }
+ | FetchAttribute::Rfc822
+ | FetchAttribute::Rfc822Text
+ | FetchAttribute::BodyStructure
+ )
+ })
+ }
+}
+
+#[derive(Default)]
+pub BatchMailViewBuilder<'a> struct {
+ attrs: AttributeProxy,
+ mi: Vec<MailIdentifiers>,
+ meta: Vec<MailMeta>,
+ flags: Vec<Vec<Flag>>,
+ bodies: Vec<FetchedMail<'a>>,
+}
+impl BatchMailViewBuilder<'a> {
+ fn new(req_attr: &MacroOrFetchAttributes) -> Self {
+ Self {
+ attrs: AttributeProxy::new(req_attr)
+ }
+ }
+
+ fn with_mail_identifiers(mut self, mi: Vec<MailIdentifiers>) -> Self {
+ self.mi = mi;
+ self
+ }
+
+ fn with_metadata(mut self, meta: Vec<MailMeta>) -> Self {
+ self.meta = meta;
+ self
+ }
+
+ fn with_flags(mut self, flags: Vec<Vec<Flag>>) -> Self {
+ self.flags = flags;
+ self
+ }
+
+ fn collect_bodies(mut self, FnOnce) -> Self {
+ if self.attrs.need_body() {
+
+ } else {
+ self.bodies =
+ }
+ self
+ }
+
+ fn build(self) -> Result<Vec<MailView>> {
+
+ }
+}
+
/// A MailboxView is responsible for giving the client the information
/// it needs about a mailbox, such as an initial summary of the mailbox's
/// content and continuous updates indicating when the content
@@ -252,32 +342,29 @@ impl MailboxView {
attributes: &MacroOrFetchAttributes,
is_uid_fetch: &bool,
) -> Result<Vec<Body>> {
+
+ /*
+ let mails = self.get_mail_ids(sequence_set, *is_uid_fetch)?;
+ let mails_uuid = mails
+ .iter()
+ .map(|mi| mi.uuid)
+ .collect::<Vec<_>>();
+
+ let mails_meta = self.mailbox.fetch_meta(&mails_uuid).await?;
+ */
+
+ // mail identifiers
let mails = self.get_mail_ids(sequence_set, *is_uid_fetch)?;
let mails_uuid = mails
.iter()
.map(|(_i, _uid, uuid)| *uuid)
.collect::<Vec<_>>();
- let mails_meta = self.mailbox.fetch_meta(&mails_uuid).await?;
- let mut fetch_attrs = match attributes {
- MacroOrFetchAttributes::Macro(m) => m.expand(),
- MacroOrFetchAttributes::FetchAttributes(a) => a.clone(),
- };
- if *is_uid_fetch && !fetch_attrs.contains(&FetchAttribute::Uid) {
- fetch_attrs.push(FetchAttribute::Uid);
- }
- let need_body = fetch_attrs.iter().any(|x| {
- matches!(
- x,
- FetchAttribute::Body
- | FetchAttribute::BodyExt { .. }
- | FetchAttribute::Rfc822
- | FetchAttribute::Rfc822Text
- | FetchAttribute::BodyStructure
- )
- });
+ // mail metadata
+ let mails_meta = self.mailbox.fetch_meta(&mails_uuid).await?;
+ // fectch email body and transform to a state usable by select
let mails = if need_body {
let mut iter = mails
.into_iter()
@@ -300,16 +387,16 @@ impl MailboxView {
.collect::<Vec<_>>()
};
- let mut ret = vec![];
- for (i, uid, uuid, meta, body) in mails {
- let mut attributes = vec![];
-
- let (_uid2, flags) = self
+ // add flags
+ let mails = mails.into_iter().filter_map(|(i, uid, uuid, meta, body)|
+ self
.known_state
.table
.get(&uuid)
- .ok_or_else(|| anyhow!("Mail not in uidindex table: {}", uuid))?;
+ .map(|(_uid2, flags)| (i, uid, uuid, meta, flags, body)))
+ .collect::<Vec<_>>();
+ // parse email body / headers
let fetched = match &body {
Some(m) => {
FetchedMail::Full(eml_codec::parse_message(m).or(Err(anyhow!("Invalid mail body")))?.1)
@@ -319,6 +406,16 @@ impl MailboxView {
}
};
+ // do the logic
+ select_mail_fragments(fetch_attrs, mails)
+ }
+
+ todo!();
+
+ let mut ret = vec![];
+ for (i, uid, uuid, meta, flags, body) in mails {
+ let mut attributes = vec![];
+
for attr in fetch_attrs.iter() {
match attr {
FetchAttribute::Uid => attributes.push(MessageAttribute::Uid(uid)),
@@ -433,8 +530,8 @@ impl MailboxView {
// ----
- // Gets the UIDs and UUIDs of mails identified by a SequenceSet of
- // sequence numbers
+ // Gets the IMAP ID, the IMAP UIDs and, the Aerogramme UUIDs of mails identified by a SequenceSet of
+ // sequence numbers (~ IMAP selector)
fn get_mail_ids(
&self,
sequence_set: &SequenceSet,