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