use std::collections::HashMap; use chrono::{DateTime,FixedOffset,ParseError}; #[derive(Debug, PartialEq)] pub struct AddrSpec { pub local_part: String, pub domain: String, } impl AddrSpec { pub fn fully_qualified(&self) -> String { format!("{}@{}", self.local_part, self.domain) } } #[derive(Debug, PartialEq)] pub struct MailboxRef { // The actual "email address" like hello@example.com pub addrspec: AddrSpec, pub name: Option, } impl From for MailboxRef { fn from(addr: AddrSpec) -> Self { MailboxRef { name: None, addrspec: addr, } } } #[derive(Debug, PartialEq)] pub struct GroupRef { pub name: String, pub participants: Vec, } #[derive(Debug, PartialEq)] pub enum AddressRef { Single(MailboxRef), Many(GroupRef), } impl From for AddressRef { fn from(mx: MailboxRef) -> Self { AddressRef::Single(mx) } } impl From for AddressRef { fn from(grp: GroupRef) -> Self { AddressRef::Many(grp) } } #[derive(Debug, PartialEq)] pub struct MessageId<'a> { pub left: &'a str, pub right: &'a str, } #[derive(Debug, PartialEq)] pub enum FieldBody<'a, T> { Correct(T), Failed(&'a str), } #[derive(Debug, PartialEq)] pub enum Field<'a> { // 3.6.1. The Origination Date Field Date(FieldBody<'a, DateTime>), // 3.6.2. Originator Fields From(FieldBody<'a, Vec>), Sender(FieldBody<'a, MailboxRef>), ReplyTo(FieldBody<'a, Vec>), // 3.6.3. Destination Address Fields To(FieldBody<'a, Vec>), Cc(FieldBody<'a, Vec>), Bcc(FieldBody<'a, Vec>), // 3.6.4. Identification Fields MessageID(FieldBody<'a, MessageId<'a>>), InReplyTo(FieldBody<'a, Vec>>), References(FieldBody<'a, Vec>>), // 3.6.5. Informational Fields Subject(FieldBody<'a, String>), Comments(FieldBody<'a, String>), Keywords(FieldBody<'a, Vec>), // 3.6.6 Resent Fields (not implemented) // 3.6.7 Trace Fields Received(FieldBody<'a, &'a str>), ReturnPath(FieldBody<'a, Option>), // 3.6.8. Optional Fields Optional(&'a str, String), // None Rescue(&'a str), } /// Permissive Header Section /// /// This is a structure intended for parsing/decoding, /// hence it's support cases where the email is considered /// as invalid according to RFC5322 but for which we can /// still extract some data. #[derive(Debug, PartialEq, Default)] pub struct HeaderSection<'a> { // 3.6.1. The Origination Date Field pub date: Option>, // 3.6.2. Originator Fields pub from: Vec, pub sender: Option, pub reply_to: Vec, // 3.6.3. Destination Address Fields pub to: Vec, pub cc: Vec, pub bcc: Vec, // 3.6.4. Identification Fields pub msg_id: Option>, pub in_reply_to: Vec>, pub references: Vec>, // 3.6.5. Informational Fields pub subject: Option, pub comments: Vec, pub keywords: Vec, // 3.6.6 Not implemented // 3.6.7 Trace Fields pub return_path: Vec, pub received: Vec<&'a str>, // 3.6.8. Optional Fields pub optional: HashMap<&'a str, String>, // Recovery pub bad_fields: Vec>, pub unparsed: Vec<&'a str>, }