aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-07-15 18:16:06 +0200
committerAlex Auvolat <alex@adnab.me>2022-07-15 18:16:06 +0200
commit8c47687d8ebeb80771872864a41e38c9168773ca (patch)
treef4339996d53e99d710f375cdd1666cd96915f48c
parent1f336cad2bf418bcf025ea37d53c1fcf85004d27 (diff)
downloadaerogramme-8c47687d8ebeb80771872864a41e38c9168773ca.tar.gz
aerogramme-8c47687d8ebeb80771872864a41e38c9168773ca.zip
Implement Fetch BODY[HEADERS.FIELDS] and BODY[HEADER.FIELDS.NOT]
-rw-r--r--src/imap/mailbox_view.rs37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/imap/mailbox_view.rs b/src/imap/mailbox_view.rs
index 73065fb..8844b3f 100644
--- a/src/imap/mailbox_view.rs
+++ b/src/imap/mailbox_view.rs
@@ -9,7 +9,7 @@ use chrono::{Offset, TimeZone, Utc};
use futures::stream::{FuturesOrdered, StreamExt};
use imap_codec::types::address::Address;
use imap_codec::types::body::{BasicFields, Body as FetchBody, BodyStructure, SpecificFields};
-use imap_codec::types::core::{Atom, IString, NString};
+use imap_codec::types::core::{AString, Atom, IString, NString};
use imap_codec::types::datetime::MyDateTime;
use imap_codec::types::envelope::Envelope;
use imap_codec::types::fetch_attributes::{
@@ -1007,6 +1007,40 @@ fn get_message_section<'a>(
.into())
},
),
+ Some(
+ FetchSection::HeaderFields(part, fields) | FetchSection::HeaderFieldsNot(part, fields),
+ ) => {
+ let invert = matches!(section, Some(FetchSection::HeaderFieldsNot(_, _)));
+ let fields = fields
+ .iter()
+ .map(|x| match x {
+ AString::Atom(a) => a.as_bytes(),
+ AString::String(IString::Literal(l)) => l.as_slice(),
+ AString::String(IString::Quoted(q)) => q.as_bytes(),
+ })
+ .collect::<Vec<_>>();
+
+ map_subpart_msg(
+ parsed,
+ part.as_ref().map(|p| p.0.as_slice()).unwrap_or(&[]),
+ |part_msg| {
+ let mut ret = vec![];
+ for (hn, hv) in part_msg.get_raw_headers() {
+ if fields
+ .as_slice()
+ .iter()
+ .any(|x| (*x == hn.as_str().as_bytes()) ^ invert)
+ {
+ ret.extend(hn.as_str().as_bytes());
+ ret.extend(b": ");
+ ret.extend(hv.as_bytes());
+ }
+ }
+ ret.extend(b"\r\n");
+ Ok(ret.into())
+ },
+ )
+ }
Some(FetchSection::Part(part)) => map_subpart(parsed, part.0.as_slice(), |_msg, part| {
let bytes = match part {
MessagePart::Text(p) | MessagePart::Html(p) => p.body.as_bytes().to_vec(),
@@ -1040,7 +1074,6 @@ fn get_message_section<'a>(
Ok(ret.into())
}),
None => Ok(parsed.raw_message.clone()),
- _ => bail!("Unimplemented: section {:?}", section),
}
}