1use std::fmt::Display;
3use std::fmt::Formatter;
4use std::hash::Hash;
5use std::hash::Hasher;
6
7use ordered_float::OrderedFloat;
8use serde::Deserialize;
9use serde::Serialize;
10
11#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
13#[serde(rename_all = "PascalCase")]
14pub struct InternalModelFormat {
15 pub models: Vec<Model>,
17}
18
19#[derive(Serialize, Deserialize, Debug, Clone)]
21#[serde(rename_all = "PascalCase")]
22pub struct Model {
23 pub name: String,
25
26 pub fields: Vec<Field>,
28
29 #[serde(default)]
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub source_defined_at: Option<Source>,
33}
34
35impl PartialEq for Model {
36 fn eq(&self, other: &Self) -> bool {
37 self.name == other.name && self.fields == other.fields
38 }
39}
40
41impl Hash for Model {
42 fn hash<H: Hasher>(&self, state: &mut H) {
43 self.fields.hash(state);
44 self.name.hash(state);
45 }
46
47 fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
48 where
49 Self: Sized,
50 {
51 data.iter().for_each(|x| x.hash(state));
52 }
53}
54
55#[derive(Serialize, Deserialize, Debug, Clone)]
57#[serde(rename_all = "PascalCase")]
58pub struct Field {
59 pub name: String,
61
62 #[serde(rename = "Type")]
64 pub db_type: DbType,
65
66 pub annotations: Vec<Annotation>,
68
69 #[serde(default)]
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub source_defined_at: Option<Source>,
73}
74
75impl PartialEq for Field {
76 fn eq(&self, other: &Self) -> bool {
77 self.name == other.name
78 && self.db_type == other.db_type
79 && self.annotations == other.annotations
80 }
81}
82
83impl Hash for Field {
84 fn hash<H: Hasher>(&self, state: &mut H) {
85 self.name.hash(state);
86 self.annotations.hash(state);
87 self.db_type.hash(state);
88 }
89
90 fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
91 where
92 Self: Sized,
93 {
94 data.iter().for_each(|x| x.hash(state));
95 }
96}
97
98#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
101#[serde(rename_all = "PascalCase")]
102pub struct Source {
103 pub file: String,
105 pub line: usize,
107 pub column: usize,
109}
110
111#[allow(missing_docs)]
113#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, PartialEq, Eq)]
114#[serde(rename_all = "lowercase")]
115pub enum DbType {
116 VarChar,
117 Binary,
118 Int8,
119 Int16,
120 Int32,
121 Int64,
122 #[serde(rename = "float_number")]
123 Float,
124 #[serde(rename = "double_number")]
125 Double,
126 Boolean,
127 Date,
128 DateTime,
129 Timestamp,
130 Time,
131 Choices,
132 Uuid,
133 MacAddress,
134 IpNetwork,
135 BitVec,
136}
137
138#[non_exhaustive]
140#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
141#[serde(tag = "Type", content = "Value")]
142#[serde(rename_all = "snake_case")]
143pub enum Annotation {
144 AutoCreateTime,
147 AutoUpdateTime,
150 AutoIncrement,
152 Choices(Vec<String>),
154 DefaultValue(DefaultValue),
156 Index(Option<IndexValue>),
158 MaxLength(i32),
160 NotNull,
162 PrimaryKey,
164 Unique,
166 ForeignKey(ForeignKey),
168}
169
170#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, Default)]
172#[serde(rename_all = "PascalCase")]
173pub struct ForeignKey {
174 pub table_name: String,
176 pub column_name: String,
178 pub on_delete: ReferentialAction,
180 pub on_update: ReferentialAction,
182}
183
184#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, PartialEq, Eq)]
188#[serde(rename_all = "PascalCase")]
189pub enum ReferentialAction {
190 Restrict,
192 Cascade,
194 SetNull,
196 SetDefault,
198}
199
200impl Default for ReferentialAction {
201 fn default() -> Self {
202 Self::Restrict
203 }
204}
205
206impl Display for ReferentialAction {
207 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
208 match self {
209 ReferentialAction::Restrict => write!(f, "RESTRICT"),
210 ReferentialAction::Cascade => write!(f, "CASCADE"),
211 ReferentialAction::SetNull => write!(f, "SET NULL"),
212 ReferentialAction::SetDefault => write!(f, "SET DEFAULT"),
213 }
214 }
215}
216
217#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
219#[serde(rename_all = "PascalCase")]
220pub struct IndexValue {
221 pub name: String,
224
225 #[serde(default)]
228 #[serde(skip_serializing_if = "Option::is_none")]
229 pub priority: Option<i32>,
230}
231
232#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]
234#[serde(untagged)]
235pub enum DefaultValue {
236 String(String),
238 Integer(i64),
240 Float(OrderedFloat<f64>),
242 Boolean(bool),
244}