doido_auth/generators/
mod.rs1pub mod field;
5pub mod migration_support;
6pub mod names;
7pub mod route_injector;
8
9pub use field::Field;
10pub use names::{to_pascal, to_snake, to_table_name};
11
12pub mod controller;
13pub mod install;
14pub mod scaffold;
15
16pub use controller::AuthControllerGenerator;
17pub use install::AuthInstallGenerator;
18pub use scaffold::AuthScaffoldGenerator;
19
20use doido_core::Result;
21
22#[derive(Debug, Clone)]
24pub struct GeneratedFile {
25 pub path: String,
26 pub content: String,
27}
28
29pub trait AuthGenerator: Send + Sync {
32 fn name(&self) -> &str;
33 fn generate(&self, args: &[&str]) -> Result<Vec<GeneratedFile>>;
34}
35
36pub trait AuthGeneratorRegistry {
38 fn register_auth(&mut self, generator: Box<dyn AuthGenerator>);
39}
40
41pub fn register(reg: &mut impl AuthGeneratorRegistry) {
43 reg.register_auth(Box::new(install::AuthInstallGenerator));
44 reg.register_auth(Box::new(controller::AuthControllerGenerator));
45 reg.register_auth(Box::new(scaffold::AuthScaffoldGenerator));
46}
47
48pub(crate) fn template(rel: &str) -> &'static str {
50 match rel {
51 "migration.rs.template" => include_str!("../../templates/migration.rs.template"),
52 "user.rs.template" => include_str!("../../templates/user.rs.template"),
53 "auth/mod.rs.template" => include_str!("../../templates/auth/mod.rs.template"),
54 "auth/sessions_controller_html.rs.template" => {
55 include_str!("../../templates/auth/sessions_controller_html.rs.template")
56 }
57 "auth/sessions_controller_api.rs.template" => {
58 include_str!("../../templates/auth/sessions_controller_api.rs.template")
59 }
60 "auth/registrations_controller_html.rs.template" => {
61 include_str!("../../templates/auth/registrations_controller_html.rs.template")
62 }
63 "auth/registrations_controller_api.rs.template" => {
64 include_str!("../../templates/auth/registrations_controller_api.rs.template")
65 }
66 "auth/passwords_controller_html.rs.template" => {
67 include_str!("../../templates/auth/passwords_controller_html.rs.template")
68 }
69 "auth/passwords_controller_api.rs.template" => {
70 include_str!("../../templates/auth/passwords_controller_api.rs.template")
71 }
72 "auth/oauth_controller.rs.template" => {
73 include_str!("../../templates/auth/oauth_controller.rs.template")
74 }
75 "auth/two_factor_controller_html.rs.template" => {
76 include_str!("../../templates/auth/two_factor_controller_html.rs.template")
77 }
78 "auth/two_factor_controller_api.rs.template" => {
79 include_str!("../../templates/auth/two_factor_controller_api.rs.template")
80 }
81 "auth/views/sign_in.html.tera" => {
82 include_str!("../../templates/auth/views/sign_in.html.tera")
83 }
84 "auth/views/sign_up.html.tera" => {
85 include_str!("../../templates/auth/views/sign_up.html.tera")
86 }
87 "auth/views/password_new.html.tera" => {
88 include_str!("../../templates/auth/views/password_new.html.tera")
89 }
90 "auth/views/password_edit.html.tera" => {
91 include_str!("../../templates/auth/views/password_edit.html.tera")
92 }
93 "auth/views/two_factor.html.tera" => {
94 include_str!("../../templates/auth/views/two_factor.html.tera")
95 }
96 "auth_controller.rs.template" => {
97 include_str!("../../templates/auth_controller.rs.template")
98 }
99 "scaffold/controller_html.rs.template" => {
100 include_str!("../../templates/scaffold/controller_html.rs.template")
101 }
102 "scaffold/controller_api.rs.template" => {
103 include_str!("../../templates/scaffold/controller_api.rs.template")
104 }
105 "scaffold/model.rs.template" => include_str!("../../templates/scaffold/model.rs.template"),
106 "scaffold/views/index.html.tera" => {
107 include_str!("../../templates/scaffold/views/index.html.tera")
108 }
109 "scaffold/views/show.html.tera" => {
110 include_str!("../../templates/scaffold/views/show.html.tera")
111 }
112 "scaffold/views/new.html.tera" => {
113 include_str!("../../templates/scaffold/views/new.html.tera")
114 }
115 "scaffold/views/edit.html.tera" => {
116 include_str!("../../templates/scaffold/views/edit.html.tera")
117 }
118 "scaffold/views/_form.html.tera" => {
119 include_str!("../../templates/scaffold/views/_form.html.tera")
120 }
121 other => panic!("unknown auth generator template: {other}"),
122 }
123}
124
125pub(crate) fn register_module(existing: &str, module: &str, marker: &str) -> String {
127 let decl = format!("pub mod {module};");
128 if existing.lines().any(|l| l.trim() == decl) {
129 return existing.to_string();
130 }
131 let mut lines: Vec<String> = existing.lines().map(String::from).collect();
132 match lines.iter().position(|l| l.contains(marker)) {
133 Some(i) => lines.insert(i, decl),
134 None => lines.push(decl),
135 }
136 let mut out = lines.join("\n");
137 out.push('\n');
138 out
139}