Skip to content

Commit 0c6f27b

Browse files
L33gn21claude
andcommitted
refactor(exporter): split Prisma exporter into mod/render/types/enums
Mirrors the sqlmodel/sqlalchemy 4-file convention. mod.rs is now a thin orchestrator; render.rs holds model rendering and relation logic; types.rs holds column-type mapping; enums.rs holds enum rendering and naming helpers. Public API surface (PrismaExporter, PrismaExporterWithConfig, export, render_entity, render_entity_with_schema, to_pascal_case_for_tests) unchanged. All 565 tests pass with byte-identical snapshot output. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 88bde9e commit 0c6f27b

4 files changed

Lines changed: 551 additions & 493 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use vespertide_core::schema::column::EnumValues;
2+
3+
pub(super) fn render_enum(name: &str, values: &EnumValues) -> String {
4+
let enum_name = to_pascal_case(name);
5+
let mut lines = Vec::new();
6+
lines.push(format!("enum {enum_name} {{"));
7+
match values {
8+
EnumValues::String(vals) => {
9+
for val in vals {
10+
let variant = to_screaming_snake(val);
11+
if variant == *val {
12+
lines.push(format!(" {variant}"));
13+
} else {
14+
lines.push(format!(" {variant} @map(\"{val}\")"));
15+
}
16+
}
17+
}
18+
EnumValues::Integer(vals) => {
19+
// Prisma doesn't support integer enums natively; emit as string variants with comment
20+
for val in vals {
21+
let variant = to_screaming_snake(&val.name);
22+
let value = val.value;
23+
lines.push(format!(" {variant} // = {value}"));
24+
}
25+
}
26+
}
27+
lines.push("}".into());
28+
lines.join("\n")
29+
}
30+
31+
pub(super) fn to_pascal_case(s: &str) -> String {
32+
s.split('_')
33+
.map(|word| {
34+
let mut chars = word.chars();
35+
match chars.next() {
36+
None => String::new(),
37+
Some(first) => first.to_uppercase().chain(chars).collect(),
38+
}
39+
})
40+
.collect()
41+
}
42+
43+
pub(super) fn to_screaming_snake(s: &str) -> String {
44+
let mut result = String::new();
45+
let mut prev_lower = false;
46+
for ch in s.chars() {
47+
if ch.is_uppercase() && prev_lower {
48+
result.push('_');
49+
}
50+
if ch.is_alphanumeric() {
51+
result.push(ch.to_ascii_uppercase());
52+
prev_lower = ch.is_lowercase();
53+
} else {
54+
result.push('_');
55+
prev_lower = false;
56+
}
57+
}
58+
result.trim_end_matches('_').to_string()
59+
}

0 commit comments

Comments
 (0)