1use serde::{Deserialize, Serialize};
24use crate::validator::Validator;
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct Schema {
29 pub tables: Vec<TableDef>,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct TableDef {
35 pub name: String,
36 pub columns: Vec<ColumnDef>,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct ColumnDef {
42 pub name: String,
43 #[serde(rename = "type", alias = "typ")]
44 pub typ: String,
45 #[serde(default)]
46 pub nullable: bool,
47 #[serde(default)]
48 pub primary_key: bool,
49}
50
51impl Schema {
52 pub fn new() -> Self {
54 Self { tables: Vec::new() }
55 }
56
57 pub fn add_table(&mut self, table: TableDef) {
59 self.tables.push(table);
60 }
61
62 pub fn to_validator(&self) -> Validator {
64 let mut v = Validator::new();
65 for table in &self.tables {
66 let cols: Vec<&str> = table.columns.iter().map(|c| c.name.as_str()).collect();
67 v.add_table(&table.name, &cols);
68 }
69 v
70 }
71
72 pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
74 serde_json::from_str(json)
75 }
76}
77
78impl Default for Schema {
79 fn default() -> Self {
80 Self::new()
81 }
82}
83
84impl TableDef {
85 pub fn new(name: &str) -> Self {
87 Self {
88 name: name.to_string(),
89 columns: Vec::new(),
90 }
91 }
92
93 pub fn add_column(&mut self, col: ColumnDef) {
95 self.columns.push(col);
96 }
97
98 pub fn column(mut self, name: &str, typ: &str) -> Self {
100 self.columns.push(ColumnDef {
101 name: name.to_string(),
102 typ: typ.to_string(),
103 nullable: true,
104 primary_key: false,
105 });
106 self
107 }
108
109 pub fn pk(mut self, name: &str, typ: &str) -> Self {
111 self.columns.push(ColumnDef {
112 name: name.to_string(),
113 typ: typ.to_string(),
114 nullable: false,
115 primary_key: true,
116 });
117 self
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_schema_from_json() {
127 let json = r#"{
128 "tables": [{
129 "name": "users",
130 "columns": [
131 { "name": "id", "type": "uuid", "nullable": false, "primary_key": true },
132 { "name": "email", "type": "varchar", "nullable": false }
133 ]
134 }]
135 }"#;
136
137 let schema = Schema::from_json(json).unwrap();
138 assert_eq!(schema.tables.len(), 1);
139 assert_eq!(schema.tables[0].name, "users");
140 assert_eq!(schema.tables[0].columns.len(), 2);
141 }
142
143 #[test]
144 fn test_schema_to_validator() {
145 let schema = Schema {
146 tables: vec![
147 TableDef::new("users").pk("id", "uuid").column("email", "varchar"),
148 ],
149 };
150
151 let validator = schema.to_validator();
152 assert!(validator.validate_table("users").is_ok());
153 assert!(validator.validate_column("users", "id").is_ok());
154 assert!(validator.validate_column("users", "email").is_ok());
155 }
156
157 #[test]
158 fn test_table_builder() {
159 let table = TableDef::new("orders")
160 .pk("id", "uuid")
161 .column("total", "decimal")
162 .column("status", "varchar");
163
164 assert_eq!(table.columns.len(), 3);
165 assert!(table.columns[0].primary_key);
166 }
167}