1use std::fmt;
2
3#[derive(Debug)]
4pub struct HeaderField {
5 pub name: String,
6 pub value: HeaderFieldValue,
7}
8
9#[derive(Debug, std::cmp::PartialEq)]
10pub enum EmailAddress {
11 AddressOnly { address: String },
12 NameAndEmailAddress { name: String, address: String },
13}
14
15#[derive(Debug, std::cmp::PartialEq)]
16pub enum HeaderFieldValue {
17 SingleEmailAddress(EmailAddress),
18 MultipleEmailAddresses(Vec<EmailAddress>),
19 Unstructured(String),
20 Empty,
21}
22
23#[derive(Debug, Default)]
24pub struct Eml {
25 pub headers: Vec<HeaderField>,
26 pub from: Option<HeaderFieldValue>,
27 pub to: Option<HeaderFieldValue>,
28 pub subject: Option<String>,
29 pub body: Option<String>,
30}
31
32impl fmt::Display for EmailAddress {
33 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34 match self {
35 EmailAddress::AddressOnly { address } => write!(f, "{address}"),
36 EmailAddress::NameAndEmailAddress { name, address } => {
37 write!(f, r#""{name}" <{address}>"#)
38 }
39 }
40 }
41}
42
43impl fmt::Display for HeaderFieldValue {
46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 match self {
48 HeaderFieldValue::SingleEmailAddress(address) => write!(f, "{address}"),
49 HeaderFieldValue::MultipleEmailAddresses(addresses) => {
50 let mut combined = String::with_capacity(20 * addresses.len());
52 addresses.iter().enumerate().for_each(|(i, a)| {
53 if i > 0 {
54 combined.push_str(", ");
55 }
56 combined.push_str(&a.to_string());
57 });
58 write!(f, "{combined}")
59 }
60 HeaderFieldValue::Unstructured(s) => write!(f, "{s}"),
61 HeaderFieldValue::Empty => write!(f, ""),
62 }
63 }
64}