1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct Schema {
5 pub models: Vec<Model>,
6}
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Model {
10 pub name: String,
11 pub fields: Vec<Field>,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct Field {
16 pub name: String,
17 pub type_name: String,
18 pub modifiers: Vec<Modifier>,
19 pub attributes: Vec<Attribute>,
20}
21
22impl Field {
23 pub fn get_default_value(&self) -> Option<String> {
24 for attr in &self.attributes {
25 if attr.name == "default" {
26 return attr.args.as_ref().map(|args| {
27 let trimmed = if args.starts_with('(') && args.ends_with(')') {
28 &args[1..args.len()-1]
29 } else {
30 args
31 };
32
33 if (trimmed.starts_with('\'') && trimmed.ends_with('\'')) ||
34 (trimmed.starts_with('"') && trimmed.ends_with('"')) {
35 trimmed[1..trimmed.len()-1].to_string()
36 } else {
37 trimmed.to_string()
38 }
39 });
40 }
41 }
42 None
43 }
44
45 pub fn is_jsonb_default_file(&self) -> bool {
46 self.get_default_value()
47 .map(|v| v.ends_with(".json"))
48 .unwrap_or(false)
49 }
50
51 pub fn get_jsonb_default_path(&self) -> Option<String> {
52 if self.type_name == "JsonB" && self.is_jsonb_default_file() {
53 self.get_default_value()
54 } else {
55 None
56 }
57 }
58
59 pub fn get_audit_model(&self) -> Option<String> {
60 for attr in &self.attributes {
61 if attr.name == "audit" {
62 return attr.args.as_ref().map(|args| {
63
64 let trimmed = if args.starts_with('(') && args.ends_with(')') {
65 &args[1..args.len()-1]
66 } else {
67 args
68 };
69 trimmed.trim().to_string()
70 });
71 }
72 }
73 None
74 }
75
76 pub fn is_sql_default(&self) -> bool {
77 self.get_default_value().is_some() && !self.is_jsonb_default_file()
78 }
79
80
81 pub fn get_default_from_file(&self) -> Result<String, Box<dyn std::error::Error>> {
82 if let Some(value) = self.get_default_value() {
83 if value.starts_with("./") || value.starts_with("../") {
84 let content = std::fs::read_to_string(&value)?;
85 return Ok(content);
86 }
87 Ok(value)
88 } else {
89 Err("No default specified".into())
90 }
91 }
92}
93
94
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub enum Modifier {
98 PrimaryKey,
99 NotNull,
100 Nullable,
101 Unique,
102 ForeignKey { model: String, field: Option<String> },
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct Attribute {
107 pub name: String,
108 pub args: Option<String>,
109}