Skip to main content

doido_generators/generators/
templates_gen.rs

1use crate::generator::{GeneratedFile, Generator};
2use crate::templates::builtin_templates;
3use doido_core::{anyhow::anyhow, Result};
4
5/// `doido generate templates [name]` — ejects the built-in default templates
6/// into the project's `templates/` directory so they can be customized. With a
7/// generator name, only that generator's templates are ejected.
8pub struct TemplatesGenerator;
9
10impl Generator for TemplatesGenerator {
11    fn name(&self) -> &str {
12        "templates"
13    }
14
15    fn generate(&self, args: &[&str]) -> Result<Vec<GeneratedFile>> {
16        let prefix = match args.first().copied() {
17            None => None,
18            Some(name) => Some(prefix_for(name)?),
19        };
20
21        let files: Vec<GeneratedFile> = builtin_templates()
22            .iter()
23            .filter(|(rel, _)| prefix.is_none_or(|p| rel.starts_with(p)))
24            .map(|(rel, content)| GeneratedFile {
25                path: format!("templates/{rel}"),
26                content: (*content).to_string(),
27            })
28            .collect();
29
30        Ok(files)
31    }
32}
33
34/// Maps a built-in generator name to the `templates/` prefix holding its files.
35fn prefix_for(name: &str) -> Result<&'static str> {
36    match name {
37        "controller" => Ok("controller/"),
38        "job" => Ok("job/"),
39        "mailer" => Ok("mailer/"),
40        "channel" => Ok("channel/"),
41        "migration" => Ok("migration/"),
42        "model" => Ok("models/"),
43        "scaffold" => Ok("scaffold/"),
44        other => Err(anyhow!(
45            "unknown generator '{other}' (valid: controller, job, mailer, channel, migration, model, scaffold)"
46        )),
47    }
48}