refactor imf::message::Message
This commit is contained in:
parent
63892af012
commit
4ad0aad8be
5 changed files with 87 additions and 87 deletions
|
@ -11,7 +11,7 @@ use crate::imf::address::{address_list, mailbox_list, nullable_address_list, Add
|
|||
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::message::Message;
|
||||
use crate::imf::Imf;
|
||||
use crate::imf::mime::{version, Version};
|
||||
use crate::imf::trace::{received_log, return_path, ReceivedLog};
|
||||
use crate::text::misc_token::{phrase_list, unstructured, PhraseList, Unstructured};
|
||||
|
@ -53,8 +53,8 @@ pub enum Field<'a> {
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub struct FieldList<'a>(pub Vec<Field<'a>>);
|
||||
impl<'a> FieldList<'a> {
|
||||
pub fn message(self) -> Message<'a> {
|
||||
Message::from_iter(self.0)
|
||||
pub fn imf(self) -> Imf<'a> {
|
||||
Imf::from_iter(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,8 +88,8 @@ pub fn field(input: &[u8]) -> IResult<&[u8], Field> {
|
|||
)(input)
|
||||
}
|
||||
|
||||
pub fn message(input: &[u8]) -> IResult<&[u8], Message> {
|
||||
map(header(field), |v| FieldList(v.known()).message())(input)
|
||||
pub fn imf(input: &[u8]) -> IResult<&[u8], Imf> {
|
||||
map(header(field), |v| FieldList(v.known()).imf())(input)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -111,10 +111,10 @@ 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!(
|
||||
message(fullmail),
|
||||
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."[..],
|
||||
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,
|
||||
|
@ -137,7 +137,7 @@ between the header information and the body of the message.";
|
|||
UnstrToken::Plain(&b"formatted"[..]),
|
||||
UnstrToken::Plain(&b"message"[..]),
|
||||
])),
|
||||
..Message::default()
|
||||
..Imf::default()
|
||||
}
|
||||
)),
|
||||
)
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
use crate::imf::address::AddressRef;
|
||||
use crate::imf::field::Field;
|
||||
use crate::imf::identification::MessageID;
|
||||
use crate::imf::mailbox::{AddrSpec, MailboxRef};
|
||||
use crate::imf::mime::Version;
|
||||
use crate::imf::trace::ReceivedLog;
|
||||
use crate::text::misc_token::{PhraseList, Unstructured};
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
pub struct Message<'a> {
|
||||
// 3.6.1. The Origination Date Field
|
||||
pub date: Option<DateTime<FixedOffset>>,
|
||||
|
||||
// 3.6.2. Originator Fields
|
||||
pub from: Vec<MailboxRef<'a>>,
|
||||
pub sender: Option<MailboxRef<'a>>,
|
||||
pub reply_to: Vec<AddressRef<'a>>,
|
||||
|
||||
// 3.6.3. Destination Address Fields
|
||||
pub to: Vec<AddressRef<'a>>,
|
||||
pub cc: Vec<AddressRef<'a>>,
|
||||
pub bcc: Vec<AddressRef<'a>>,
|
||||
|
||||
// 3.6.4. Identification Fields
|
||||
pub msg_id: Option<MessageID<'a>>,
|
||||
pub in_reply_to: Vec<MessageID<'a>>,
|
||||
pub references: Vec<MessageID<'a>>,
|
||||
|
||||
// 3.6.5. Informational Fields
|
||||
pub subject: Option<Unstructured<'a>>,
|
||||
pub comments: Vec<Unstructured<'a>>,
|
||||
pub keywords: Vec<PhraseList<'a>>,
|
||||
|
||||
// 3.6.6 Not implemented
|
||||
// 3.6.7 Trace Fields
|
||||
pub return_path: Vec<AddrSpec<'a>>,
|
||||
pub received: Vec<ReceivedLog<'a>>,
|
||||
|
||||
// MIME
|
||||
pub mime_version: Option<Version>,
|
||||
}
|
||||
|
||||
//@FIXME min and max limits are not enforced,
|
||||
// it may result in missing data or silently overriden data.
|
||||
impl<'a> FromIterator<Field<'a>> for Message<'a> {
|
||||
fn from_iter<I: IntoIterator<Item = Field<'a>>>(iter: I) -> Self {
|
||||
iter.into_iter()
|
||||
.fold(Message::default(), |mut section, field| {
|
||||
match field {
|
||||
Field::Date(v) => section.date = v,
|
||||
Field::From(v) => section.from.extend(v),
|
||||
Field::Sender(v) => section.sender = Some(v),
|
||||
Field::ReplyTo(v) => section.reply_to.extend(v),
|
||||
Field::To(v) => section.to.extend(v),
|
||||
Field::Cc(v) => section.cc.extend(v),
|
||||
Field::Bcc(v) => section.bcc.extend(v),
|
||||
Field::MessageID(v) => section.msg_id = Some(v),
|
||||
Field::InReplyTo(v) => section.in_reply_to.extend(v),
|
||||
Field::References(v) => section.references.extend(v),
|
||||
Field::Subject(v) => section.subject = Some(v),
|
||||
Field::Comments(v) => section.comments.push(v),
|
||||
Field::Keywords(v) => section.keywords.push(v),
|
||||
Field::ReturnPath(v) => v.map(|x| section.return_path.push(x)).unwrap_or(()),
|
||||
Field::Received(v) => section.received.push(v),
|
||||
Field::MIMEVersion(v) => section.mime_version = Some(v),
|
||||
};
|
||||
section
|
||||
})
|
||||
}
|
||||
}
|
|
@ -3,6 +3,77 @@ pub mod datetime;
|
|||
pub mod field;
|
||||
pub mod identification;
|
||||
pub mod mailbox;
|
||||
pub mod message;
|
||||
pub mod mime;
|
||||
pub mod trace;
|
||||
|
||||
use crate::imf::address::AddressRef;
|
||||
use crate::imf::field::Field;
|
||||
use crate::imf::identification::MessageID;
|
||||
use crate::imf::mailbox::{AddrSpec, MailboxRef};
|
||||
use crate::imf::mime::Version;
|
||||
use crate::imf::trace::ReceivedLog;
|
||||
use crate::text::misc_token::{PhraseList, Unstructured};
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
pub struct Imf<'a> {
|
||||
// 3.6.1. The Origination Date Field
|
||||
pub date: Option<DateTime<FixedOffset>>,
|
||||
|
||||
// 3.6.2. Originator Fields
|
||||
pub from: Vec<MailboxRef<'a>>,
|
||||
pub sender: Option<MailboxRef<'a>>,
|
||||
pub reply_to: Vec<AddressRef<'a>>,
|
||||
|
||||
// 3.6.3. Destination Address Fields
|
||||
pub to: Vec<AddressRef<'a>>,
|
||||
pub cc: Vec<AddressRef<'a>>,
|
||||
pub bcc: Vec<AddressRef<'a>>,
|
||||
|
||||
// 3.6.4. Identification Fields
|
||||
pub msg_id: Option<MessageID<'a>>,
|
||||
pub in_reply_to: Vec<MessageID<'a>>,
|
||||
pub references: Vec<MessageID<'a>>,
|
||||
|
||||
// 3.6.5. Informational Fields
|
||||
pub subject: Option<Unstructured<'a>>,
|
||||
pub comments: Vec<Unstructured<'a>>,
|
||||
pub keywords: Vec<PhraseList<'a>>,
|
||||
|
||||
// 3.6.6 Not implemented
|
||||
// 3.6.7 Trace Fields
|
||||
pub return_path: Vec<AddrSpec<'a>>,
|
||||
pub received: Vec<ReceivedLog<'a>>,
|
||||
|
||||
// MIME
|
||||
pub mime_version: Option<Version>,
|
||||
}
|
||||
|
||||
//@FIXME min and max limits are not enforced,
|
||||
// it may result in missing data or silently overriden data.
|
||||
impl<'a> FromIterator<Field<'a>> for Imf<'a> {
|
||||
fn from_iter<I: IntoIterator<Item = Field<'a>>>(iter: I) -> Self {
|
||||
iter.into_iter()
|
||||
.fold(Imf::default(), |mut section, field| {
|
||||
match field {
|
||||
Field::Date(v) => section.date = v,
|
||||
Field::From(v) => section.from.extend(v),
|
||||
Field::Sender(v) => section.sender = Some(v),
|
||||
Field::ReplyTo(v) => section.reply_to.extend(v),
|
||||
Field::To(v) => section.to.extend(v),
|
||||
Field::Cc(v) => section.cc.extend(v),
|
||||
Field::Bcc(v) => section.bcc.extend(v),
|
||||
Field::MessageID(v) => section.msg_id = Some(v),
|
||||
Field::InReplyTo(v) => section.in_reply_to.extend(v),
|
||||
Field::References(v) => section.references.extend(v),
|
||||
Field::Subject(v) => section.subject = Some(v),
|
||||
Field::Comments(v) => section.comments.push(v),
|
||||
Field::Keywords(v) => section.keywords.push(v),
|
||||
Field::ReturnPath(v) => v.map(|x| section.return_path.push(x)).unwrap_or(()),
|
||||
Field::Received(v) => section.received.push(v),
|
||||
Field::MIMEVersion(v) => section.mime_version = Some(v),
|
||||
};
|
||||
section
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ pub fn email(input: &[u8]) -> Result<part::part::Message, error::EMLError> {
|
|||
.map_err(error::EMLError::ParseError)
|
||||
}
|
||||
|
||||
pub fn imf(input: &[u8]) -> Result<imf::message::Message, error::EMLError> {
|
||||
imf::field::message(input)
|
||||
pub fn imf(input: &[u8]) -> Result<imf::Imf, error::EMLError> {
|
||||
imf::field::imf(input)
|
||||
.map(|(_, v)| v)
|
||||
.map_err(error::EMLError::ParseError)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ pub struct Multipart<'a>(pub mime::mime::Multipart<'a>, pub Vec<AnyPart<'a>>);
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub struct Message<'a>(
|
||||
pub mime::mime::Message<'a>,
|
||||
pub imf::message::Message<'a>,
|
||||
pub imf::Imf<'a>,
|
||||
pub Box<AnyPart<'a>>,
|
||||
);
|
||||
|
||||
|
@ -90,7 +90,7 @@ impl<'a> MixedField<'a> {
|
|||
}
|
||||
}
|
||||
impl<'a> CompFieldList<'a, MixedField<'a>> {
|
||||
pub fn sections(self) -> (mime::mime::AnyMIME<'a>, imf::message::Message<'a>) {
|
||||
pub fn sections(self) -> (mime::mime::AnyMIME<'a>, imf::Imf<'a>) {
|
||||
let k = self.known();
|
||||
let (v1, v2): (Vec<MixedField>, Vec<MixedField>) =
|
||||
k.into_iter().partition(|v| v.mime().is_some());
|
||||
|
@ -101,7 +101,7 @@ impl<'a> CompFieldList<'a, MixedField<'a>> {
|
|||
let imf = v2
|
||||
.into_iter()
|
||||
.filter_map(|v| v.to_imf())
|
||||
.collect::<imf::message::Message>();
|
||||
.collect::<imf::Imf>();
|
||||
(mime, imf)
|
||||
}
|
||||
}
|
||||
|
@ -338,7 +338,7 @@ OoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO<br />
|
|||
&[][..],
|
||||
Message (
|
||||
base_mime,
|
||||
imf::message::Message {
|
||||
imf::Imf {
|
||||
date: Some(FixedOffset::east_opt(2 * 3600)
|
||||
.unwrap()
|
||||
.with_ymd_and_hms(2023, 07, 8, 7, 14, 29)
|
||||
|
@ -401,7 +401,7 @@ OoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO<br />
|
|||
right: &b"www.grrrndzero.org"[..],
|
||||
}),
|
||||
mime_version: Some(imf::mime::Version { major: 1, minor: 0}),
|
||||
..imf::message::Message::default()
|
||||
..imf::Imf::default()
|
||||
},
|
||||
Box::new(AnyPart::Mult(Multipart (
|
||||
mime::mime::Multipart(
|
||||
|
|
Loading…
Reference in a new issue