rainier_mail/driver.rs
1//! Where mail goes — [`MailDriver`].
2
3use rainier_support::setting_enum;
4
5setting_enum! {
6 /// Which [`Transport`](crate::Transport) to build.
7 ///
8 /// ```
9 /// use rainier_mail::MailDriver;
10 /// use rainier_support::Setting;
11 ///
12 /// assert!(!MailDriver::Log.delivers(), "nothing leaves the machine");
13 /// assert!(MailDriver::parse("smtp").unwrap().delivers());
14 /// ```
15 pub enum MailDriver: "mail driver" {
16 /// Write the message to the log and deliver nothing.
17 ///
18 /// The default, and the only safe one to have by accident: a
19 /// misconfigured production deployment fails to send mail rather than
20 /// sending it to real people from a staging database.
21 #[default]
22 Log = "log",
23
24 /// Write each message to a `.eml` file under `storage/mail`.
25 ///
26 /// Openable in a mail client, so you can check what a template actually
27 /// renders to. Delivers nothing.
28 File = "file",
29
30 /// Keep messages in memory so a test can assert on them.
31 ///
32 /// Never right outside a test — the messages go nowhere and the vector
33 /// grows until the process ends.
34 Memory = "memory",
35
36 /// A real SMTP server.
37 Smtp = "smtp",
38 }
39}
40
41impl MailDriver {
42 /// Whether a message actually leaves the machine.
43 ///
44 /// The check worth making before a seeder or a backfill: everything else
45 /// here is safe to point a hundred thousand messages at.
46 pub fn delivers(&self) -> bool {
47 matches!(self, Self::Smtp)
48 }
49
50 /// Whether the sent messages can be read back and asserted on.
51 pub fn is_inspectable(&self) -> bool {
52 matches!(self, Self::Memory | Self::File)
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use rainier_support::Setting;
60
61 #[test]
62 fn only_smtp_actually_sends() {
63 assert!(MailDriver::Smtp.delivers());
64 for driver in MailDriver::ALL.iter().filter(|d| **d != MailDriver::Smtp) {
65 assert!(!driver.delivers(), "{driver} must not send real mail");
66 }
67 }
68
69 #[test]
70 fn the_default_sends_nothing() {
71 // The property that matters: a deployment that forgot to set
72 // MAIL_DRIVER cannot mail real users.
73 assert!(!MailDriver::default().delivers());
74 }
75}