diff options
author | Alex Auvolat <alex@adnab.me> | 2022-07-15 18:16:06 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-07-15 18:16:06 +0200 |
commit | 8c47687d8ebeb80771872864a41e38c9168773ca (patch) | |
tree | f4339996d53e99d710f375cdd1666cd96915f48c | |
parent | 1f336cad2bf418bcf025ea37d53c1fcf85004d27 (diff) | |
download | aerogramme-8c47687d8ebeb80771872864a41e38c9168773ca.tar.gz aerogramme-8c47687d8ebeb80771872864a41e38c9168773ca.zip |
Implement Fetch BODY[HEADERS.FIELDS] and BODY[HEADER.FIELDS.NOT]
-rw-r--r-- | src/imap/mailbox_view.rs | 37 |
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), } } |