Configuration
The box office is about to send emails: order confirmations, and later sign-in links. Staging must never email real fans, so the mail settings change with every deployment.
In Margaret, a setting lives in the constructor that needs it. There's no central configuration file to keep in sync.
Command line flags and environment variables
A singleton asks for a command line flag with #[console_argument], and for an environment variable with #[environment_variable]. The Mailer needs both:
The API URL and the sender are ordinary settings, so they're flags. The token is a secret, so it comes from the environment. A bool becomes a flag without a value: on staging, --mail-sandbox prints emails instead of sending them.
Client and Url come from margaret::framework::reqwest, the HTTP client Margaret ships with.
Using the mailer
Nothing sends email yet, and Margaret refuses to build a singleton that nothing uses. A small command lets the staff check the mail settings of a fresh deployment:
#[console_argument(positional)] takes the recipient without a flag name. The help text is generated:
$ box_office send-test-email --help
Sends a test email to check the mail settings
Usage: box_office send-test-email [OPTIONS] --mail-api-url <mail-api-url> --mail-sender <mail-sender> <recipient>
Arguments:
<recipient>
Options:
--mail-api-url <mail-api-url>
--mail-sender <mail-sender>
--mail-sandbox
-h, --help Print helpThe from value becomes the flag's name, exactly as written. Values are parsed into their Rust types, like Url, before any constructor runs, and an Option makes a setting optional:
$ box_office send-test-email staff@example.com --mail-api-url not-a-url --mail-sender tickets@example.com
error: invalid value 'not-a-url' for '--mail-api-url <mail-api-url>': relative URL without a baseA missing environment variable stops the command before it starts:
$ box_office send-test-email staff@example.com --mail-api-url https://mail.example.com/send --mail-sender tickets@example.com
the environment variable 'MAIL_API_TOKEN' is not setWhich commands accept a setting
A setting belongs to the singletons that ask for it, so it appears only on the commands that need them. send-test-email reaches the Mailer, so it accepts the mail flags. lineup doesn't, so it doesn't ask for them.
serve accepts a setting once something it serves reaches the singleton. Right now, nothing served sends email, so serve doesn't ask for the mail settings yet. That changes in Background services, where the box office starts sending confirmations.