2023-06-08 19:43:32 +00:00
|
|
|
use std::collections::HashMap;
|
2023-06-12 09:54:15 +00:00
|
|
|
use chrono::{DateTime,FixedOffset,ParseError};
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub enum HeaderDate {
|
|
|
|
Parsed(DateTime<FixedOffset>),
|
|
|
|
Unknown(String, ParseError),
|
|
|
|
#[default]
|
|
|
|
None,
|
|
|
|
}
|
2023-06-08 19:43:32 +00:00
|
|
|
|
2023-06-12 14:05:06 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct MailboxRef<'a> {
|
|
|
|
// The actual "email address" like hello@example.com
|
|
|
|
pub addrspec: &'a str,
|
|
|
|
pub name: Option<&'a str>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct GroupRef<'a> {
|
|
|
|
pub name: &'a str,
|
|
|
|
pub mbx: Vec<MailboxRef<'a>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum AddressRef<'a> {
|
|
|
|
Single(MailboxRef<'a>),
|
|
|
|
Many(GroupRef<'a>),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2023-06-08 19:43:32 +00:00
|
|
|
#[derive(Debug, Default)]
|
2023-06-12 14:05:06 +00:00
|
|
|
pub struct PermissiveHeaderSection<'a> {
|
2023-06-08 19:43:32 +00:00
|
|
|
pub subject: Option<String>,
|
2023-06-12 14:05:06 +00:00
|
|
|
pub from: Vec<MailboxRef<'a>>,
|
|
|
|
pub sender: Option<MailboxRef<'a>>,
|
|
|
|
pub reply_to: Vec<AddressRef<'a>>,
|
2023-06-12 09:54:15 +00:00
|
|
|
pub date: HeaderDate,
|
2023-06-08 19:43:32 +00:00
|
|
|
pub optional: HashMap<&'a str, String>,
|
|
|
|
}
|
2023-06-12 09:54:15 +00:00
|
|
|
|
|
|
|
enum InvalidEmailErr {
|
|
|
|
NoUsableDate,
|
|
|
|
}
|
|
|
|
|
2023-06-12 14:05:06 +00:00
|
|
|
impl<'a> PermissiveHeaderSection<'a> {
|
|
|
|
/// Check validity of the email
|
|
|
|
///
|
|
|
|
/// Especially check that there is no missing fields,
|
|
|
|
/// or no unique fields declared multiple times.
|
|
|
|
///
|
|
|
|
/// See: https://www.rfc-editor.org/rfc/rfc5322#section-3.6
|
|
|
|
//@FIXME could be changed to a to_StrictHeaderSection call. All fixed errors would be returned in
|
|
|
|
// a vec of errors.
|
2023-06-12 09:54:15 +00:00
|
|
|
fn is_valid(&self) -> Result<(), InvalidEmailErr> {
|
|
|
|
match self.date {
|
|
|
|
HeaderDate::Parsed(_) => (),
|
|
|
|
_ => return Err(InvalidEmailErr::NoUsableDate),
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|