Skip to main content

doido_generators/generators/
mailer.rs

1use crate::generator::{GeneratedFile, Generator};
2use crate::generators::{register_module, to_pascal, to_snake};
3use doido_core::Result;
4
5/// Fallback `app/mailers/mod.rs` when the app doesn't have one on disk yet.
6const MAILERS_MOD_BASE: &str = include_str!("../../templates/new/app/mailers/mod.rs");
7const MAILERS_MOD_PATH: &str = "app/mailers/mod.rs";
8
9pub struct MailerGenerator;
10
11impl Generator for MailerGenerator {
12    fn name(&self) -> &str {
13        "mailer"
14    }
15
16    fn generate(&self, args: &[&str]) -> Result<Vec<GeneratedFile>> {
17        let name = args.first().copied().ok_or_else(|| {
18            doido_core::anyhow::anyhow!("mailer generator requires a name argument")
19        })?;
20        let snake = to_snake(name);
21        let pascal = to_pascal(name);
22        let content =
23            crate::templates::get("mailer/mailer.rs.template").replace("{pascal}", &pascal);
24        let test = crate::templates::get("mailer/mailer_test.rs.template")
25            .replace("{pascal}", &pascal)
26            .replace("{snake}", &snake);
27
28        // Register the mailer's module in app/mailers/mod.rs.
29        let existing = std::fs::read_to_string(MAILERS_MOD_PATH)
30            .unwrap_or_else(|_| MAILERS_MOD_BASE.to_string());
31        let mailers_mod =
32            register_module(&existing, &format!("{snake}_mailer"), "@generated-mailers");
33
34        Ok(vec![
35            GeneratedFile {
36                path: format!("app/mailers/{snake}_mailer.rs"),
37                content,
38            },
39            GeneratedFile {
40                path: MAILERS_MOD_PATH.to_string(),
41                content: mailers_mod,
42            },
43            GeneratedFile {
44                path: format!("tests/{snake}_mailer_test.rs"),
45                content: test,
46            },
47        ])
48    }
49}