1pub mod address;
17pub mod email;
18
19pub use address::{
20 Address, AddressBackendError, AddressList, AddressParseError, Group, GroupParseError, Mailbox,
21 MailboxList, MailboxParseError, ParseError,
22};
23pub use email::{Email, EmailParseError};
24
25#[derive(Clone, Debug, PartialEq, Eq, Hash)]
26pub struct Envelope {
27 pub mail_from: Option<Mailbox>,
28 pub rcpt_to: Vec<Mailbox>,
29}
30
31#[derive(Clone, Debug, PartialEq, Eq)]
32pub struct Header {
33 pub name: String,
34 pub value: String,
35}
36
37#[derive(Clone, Debug, PartialEq, Eq)]
38#[non_exhaustive]
39pub enum AttachmentBody {
40 Bytes(Vec<u8>),
41}
42
43#[derive(Clone, Debug, PartialEq, Eq)]
44pub struct Attachment {
45 pub filename: Option<String>,
46 pub content_type: String,
47 pub content_id: Option<String>,
48 pub inline: bool,
49 pub body: AttachmentBody,
50}
51
52#[derive(Clone, Debug, PartialEq, Eq)]
53pub enum Body {
54 Text(String),
55 Html(String),
56 TextAndHtml { text: String, html: String },
57 Mime(MimePart),
58 RawRfc822(Vec<u8>),
59}
60
61#[derive(Clone, Debug, PartialEq, Eq)]
62pub enum MimePart {
63 Leaf {
64 content_type: String,
65 content_transfer_encoding: Option<String>,
66 content_disposition: Option<String>,
67 body: Vec<u8>,
68 },
69 Multipart {
70 content_type: String,
71 boundary: Option<String>,
72 parts: Vec<MimePart>,
73 },
74}
75
76#[derive(Clone, Debug, PartialEq, Eq)]
77pub struct Message {
78 pub from: Option<Mailbox>,
79 pub sender: Option<Mailbox>,
80 pub to: Vec<Address>,
81 pub cc: Vec<Address>,
82 pub bcc: Vec<Address>,
83 pub reply_to: Vec<Address>,
84 pub subject: Option<String>,
85 pub date: Option<String>,
86 pub message_id: Option<String>,
87 pub headers: Vec<Header>,
88 pub body: Body,
89 pub attachments: Vec<Attachment>,
90}
91
92#[derive(Clone, Debug, PartialEq, Eq)]
93pub enum MessageValidationError {
94 MissingFrom,
95 MissingRecipients,
96}
97
98impl Display for MessageValidationError {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 match self {
101 Self::MissingFrom => f.write_str("missing From header"),
102 Self::MissingRecipients => f.write_str("no recipients in To/Cc/Bcc"),
103 }
104 }
105}
106
107impl std::error::Error for MessageValidationError {}
108
109impl Message {
110 pub fn validate_basic(&self) -> Result<(), MessageValidationError> {
111 if self.from.is_none() {
112 return Err(MessageValidationError::MissingFrom);
113 }
114
115 if self.to.is_empty() && self.cc.is_empty() && self.bcc.is_empty() {
116 return Err(MessageValidationError::MissingRecipients);
117 }
118
119 Ok(())
120 }
121}
122use std::fmt::Display;