From dfb5b9fe0f7349dbb53368b52f077f4eb3e62e26 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Wed, 30 Aug 2023 11:35:46 +0200 Subject: [PATCH] refactor imf parsing --- src/imf/field.rs | 67 +++------------------------------------------ src/imf/mod.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 2 +- 3 files changed, 74 insertions(+), 65 deletions(-) diff --git a/src/imf/field.rs b/src/imf/field.rs index c9ea2bd..976bf4f 100644 --- a/src/imf/field.rs +++ b/src/imf/field.rs @@ -6,14 +6,13 @@ use nom::{ IResult, }; -use crate::header::{field_name, header}; +use crate::header::{field_name}; use crate::imf::address::{address_list, mailbox_list, nullable_address_list, AddressList}; use crate::imf::datetime::section as date; use crate::imf::identification::{msg_id, msg_list, MessageID, MessageIDList}; use crate::imf::mailbox::{mailbox, AddrSpec, MailboxList, MailboxRef}; use crate::imf::mime::{version, Version}; use crate::imf::trace::{received_log, return_path, ReceivedLog}; -use crate::imf::Imf; use crate::text::misc_token::{phrase_list, unstructured, PhraseList, Unstructured}; use crate::text::whitespace::obs_crlf; @@ -49,6 +48,9 @@ pub enum Field<'a> { MIMEVersion(Version), } +/*impl<'a> From> for Field<'a> { + fn from(raw: header::Field +}*/ pub fn field(input: &[u8]) -> IResult<&[u8], Field> { terminated( @@ -79,64 +81,3 @@ pub fn field(input: &[u8]) -> IResult<&[u8], Field> { obs_crlf, )(input) } - -pub fn imf(input: &[u8]) -> IResult<&[u8], Imf> { - map(header(field), |(known, unknown, bad)| { - let mut imf = Imf::from_iter(known); - imf.header_ext = unknown; - imf.header_bad = bad; - imf - })(input) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::imf::address::*; - use crate::imf::mailbox::*; - use crate::text::misc_token::*; - use chrono::{FixedOffset, TimeZone}; - - #[test] - fn test_header() { - let fullmail = b"Date: 7 Mar 2023 08:00:00 +0200 -From: someone@example.com -To: someone_else@example.com -Subject: An RFC 822 formatted message - -This is the plain text body of the message. Note the blank line -between the header information and the body of the message."; - - assert_eq!( - imf(fullmail), - Ok(( - &b"This is the plain text body of the message. Note the blank line\nbetween the header information and the body of the message."[..], - Imf { - date: Some(FixedOffset::east_opt(2 * 3600).unwrap().with_ymd_and_hms(2023, 3, 7, 8, 0, 0).unwrap()), - from: vec![MailboxRef { - name: None, - addrspec: AddrSpec { - local_part: LocalPart(vec![LocalPartToken::Word(Word::Atom(&b"someone"[..]))]), - domain: Domain::Atoms(vec![&b"example"[..], &b"com"[..]]), - } - }], - to: vec![AddressRef::Single(MailboxRef { - name: None, - addrspec: AddrSpec { - local_part: LocalPart(vec![LocalPartToken::Word(Word::Atom(&b"someone_else"[..]))]), - domain: Domain::Atoms(vec![&b"example"[..], &b"com"[..]]), - } - })], - subject: Some(Unstructured(vec![ - UnstrToken::Plain(&b"An"[..]), - UnstrToken::Plain(&b"RFC"[..]), - UnstrToken::Plain(&b"822"[..]), - UnstrToken::Plain(&b"formatted"[..]), - UnstrToken::Plain(&b"message"[..]), - ])), - ..Imf::default() - } - )), - ) - } -} diff --git a/src/imf/mod.rs b/src/imf/mod.rs index 7817ac7..51f1268 100644 --- a/src/imf/mod.rs +++ b/src/imf/mod.rs @@ -8,8 +8,14 @@ pub mod mailbox; pub mod mime; pub mod trace; +use nom::{ + combinator::map, + IResult, +}; + +use crate::header::header; use crate::imf::address::AddressRef; -use crate::imf::field::Field; +use crate::imf::field::{field, Field}; use crate::imf::identification::MessageID; use crate::imf::mailbox::{AddrSpec, MailboxRef}; use crate::imf::mime::Version; @@ -92,3 +98,65 @@ impl<'a> FromIterator> for Imf<'a> { }) } } + +pub fn imf(input: &[u8]) -> IResult<&[u8], Imf> { + map(header(field), |(known, unknown, bad)| { + let mut imf = Imf::from_iter(known); + imf.header_ext = unknown; + imf.header_bad = bad; + imf + })(input) +} + + +#[cfg(test)] +mod tests { + use super::*; + use crate::imf::address::*; + use crate::imf::mailbox::*; + use crate::text::misc_token::*; + use chrono::{FixedOffset, TimeZone}; + + #[test] + fn test_header() { + let fullmail = b"Date: 7 Mar 2023 08:00:00 +0200 +From: someone@example.com +To: someone_else@example.com +Subject: An RFC 822 formatted message + +This is the plain text body of the message. Note the blank line +between the header information and the body of the message."; + + assert_eq!( + imf(fullmail), + Ok(( + &b"This is the plain text body of the message. Note the blank line\nbetween the header information and the body of the message."[..], + Imf { + date: Some(FixedOffset::east_opt(2 * 3600).unwrap().with_ymd_and_hms(2023, 3, 7, 8, 0, 0).unwrap()), + from: vec![MailboxRef { + name: None, + addrspec: AddrSpec { + local_part: LocalPart(vec![LocalPartToken::Word(Word::Atom(&b"someone"[..]))]), + domain: Domain::Atoms(vec![&b"example"[..], &b"com"[..]]), + } + }], + to: vec![AddressRef::Single(MailboxRef { + name: None, + addrspec: AddrSpec { + local_part: LocalPart(vec![LocalPartToken::Word(Word::Atom(&b"someone_else"[..]))]), + domain: Domain::Atoms(vec![&b"example"[..], &b"com"[..]]), + } + })], + subject: Some(Unstructured(vec![ + UnstrToken::Plain(&b"An"[..]), + UnstrToken::Plain(&b"RFC"[..]), + UnstrToken::Plain(&b"822"[..]), + UnstrToken::Plain(&b"formatted"[..]), + UnstrToken::Plain(&b"message"[..]), + ])), + ..Imf::default() + } + )), + ) + } +} diff --git a/src/lib.rs b/src/lib.rs index b133b9e..edb327a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -98,5 +98,5 @@ pub fn parse_message(input: &[u8]) -> IResult<&[u8], part::composite::Message> { /// ); /// ``` pub fn parse_imf(input: &[u8]) -> IResult<&[u8], imf::Imf> { - imf::field::imf(input) + imf::imf(input) }