refactor imf parsing
This commit is contained in:
parent
ba59b037ef
commit
dfb5b9fe0f
3 changed files with 74 additions and 65 deletions
|
@ -6,14 +6,13 @@ use nom::{
|
||||||
IResult,
|
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::address::{address_list, mailbox_list, nullable_address_list, AddressList};
|
||||||
use crate::imf::datetime::section as date;
|
use crate::imf::datetime::section as date;
|
||||||
use crate::imf::identification::{msg_id, msg_list, MessageID, MessageIDList};
|
use crate::imf::identification::{msg_id, msg_list, MessageID, MessageIDList};
|
||||||
use crate::imf::mailbox::{mailbox, AddrSpec, MailboxList, MailboxRef};
|
use crate::imf::mailbox::{mailbox, AddrSpec, MailboxList, MailboxRef};
|
||||||
use crate::imf::mime::{version, Version};
|
use crate::imf::mime::{version, Version};
|
||||||
use crate::imf::trace::{received_log, return_path, ReceivedLog};
|
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::misc_token::{phrase_list, unstructured, PhraseList, Unstructured};
|
||||||
use crate::text::whitespace::obs_crlf;
|
use crate::text::whitespace::obs_crlf;
|
||||||
|
|
||||||
|
@ -49,6 +48,9 @@ pub enum Field<'a> {
|
||||||
|
|
||||||
MIMEVersion(Version),
|
MIMEVersion(Version),
|
||||||
}
|
}
|
||||||
|
/*impl<'a> From<header::Field<'a>> for Field<'a> {
|
||||||
|
fn from(raw: header::Field
|
||||||
|
}*/
|
||||||
|
|
||||||
pub fn field(input: &[u8]) -> IResult<&[u8], Field> {
|
pub fn field(input: &[u8]) -> IResult<&[u8], Field> {
|
||||||
terminated(
|
terminated(
|
||||||
|
@ -79,64 +81,3 @@ pub fn field(input: &[u8]) -> IResult<&[u8], Field> {
|
||||||
obs_crlf,
|
obs_crlf,
|
||||||
)(input)
|
)(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()
|
|
||||||
}
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,8 +8,14 @@ pub mod mailbox;
|
||||||
pub mod mime;
|
pub mod mime;
|
||||||
pub mod trace;
|
pub mod trace;
|
||||||
|
|
||||||
|
use nom::{
|
||||||
|
combinator::map,
|
||||||
|
IResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::header::header;
|
||||||
use crate::imf::address::AddressRef;
|
use crate::imf::address::AddressRef;
|
||||||
use crate::imf::field::Field;
|
use crate::imf::field::{field, Field};
|
||||||
use crate::imf::identification::MessageID;
|
use crate::imf::identification::MessageID;
|
||||||
use crate::imf::mailbox::{AddrSpec, MailboxRef};
|
use crate::imf::mailbox::{AddrSpec, MailboxRef};
|
||||||
use crate::imf::mime::Version;
|
use crate::imf::mime::Version;
|
||||||
|
@ -92,3 +98,65 @@ impl<'a> FromIterator<Field<'a>> 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()
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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> {
|
pub fn parse_imf(input: &[u8]) -> IResult<&[u8], imf::Imf> {
|
||||||
imf::field::imf(input)
|
imf::imf(input)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue