Skip to main content

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}