doido_generators/generators/
mailer.rs1use crate::generator::{GeneratedFile, Generator};
2use crate::generators::{register_module, to_pascal, to_snake};
3use doido_core::Result;
4
5const 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
11fn mailer_type_name(name: &str) -> String {
13 let pascal = to_pascal(name);
14 if pascal.ends_with("Mailer") {
15 pascal
16 } else {
17 format!("{pascal}Mailer")
18 }
19}
20
21fn mailer_module_snake(name: &str) -> String {
23 let snake = to_snake(name);
24 if snake.ends_with("_mailer") {
25 snake
26 } else {
27 format!("{snake}_mailer")
28 }
29}
30
31impl Generator for MailerGenerator {
32 fn name(&self) -> &str {
33 "mailer"
34 }
35
36 fn generate(&self, args: &[&str]) -> Result<Vec<GeneratedFile>> {
37 let name = args.first().copied().ok_or_else(|| {
38 doido_core::anyhow::anyhow!("mailer generator requires a name argument")
39 })?;
40 let snake = mailer_module_snake(name);
41 let pascal = mailer_type_name(name);
42 let content =
43 crate::templates::get("mailer/mailer.rs.template").replace("{pascal}", &pascal);
44 let test = crate::templates::get("mailer/mailer_test.rs.template")
45 .replace("{pascal}", &pascal)
46 .replace("{snake}", &snake);
47
48 let existing = std::fs::read_to_string(MAILERS_MOD_PATH)
50 .unwrap_or_else(|_| MAILERS_MOD_BASE.to_string());
51 let mailers_mod = register_module(&existing, &snake, "@generated-mailers");
52
53 Ok(vec![
54 GeneratedFile {
55 path: format!("app/mailers/{snake}.rs"),
56 content,
57 },
58 GeneratedFile {
59 path: MAILERS_MOD_PATH.to_string(),
60 content: mailers_mod,
61 },
62 GeneratedFile {
63 path: format!("tests/{snake}_test.rs"),
64 content: test,
65 },
66 ])
67 }
68}