1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Clone, Deserialize, Serialize)]
5pub struct Document {
6 pub datamodel: Datamodel,
7 pub schema: Schema,
8 pub mappings: Mappings,
9}
10
11#[derive(Debug, Clone, Deserialize, Serialize)]
12pub struct Mappings {
13 #[serde(rename = "modelOperations")]
14 pub model_operations: Vec<ModelMapping>,
15 #[serde(rename = "otherOperations")]
16 pub other_operations: OtherOperationMappings,
17}
18
19#[derive(Debug, Clone, Deserialize, Serialize)]
20pub struct OtherOperationMappings {
21 pub read: Vec<String>,
22 pub write: Vec<String>,
23}
24
25#[derive(Debug, Clone, Deserialize, Serialize)]
26pub struct DatamodelEnum {
27 pub name: String,
28 pub values: Vec<EnumValue>,
29 #[serde(rename = "dbName")]
30 pub db_name: Option<String>,
31 pub documentation: Option<String>,
32}
33
34#[derive(Debug, Clone, Deserialize, Serialize)]
35pub struct SchemaEnum {
36 pub name: String,
37 pub values: Vec<String>,
38}
39
40#[derive(Debug, Clone, Deserialize, Serialize)]
41pub struct EnumValue {
42 pub name: String,
43 #[serde(rename = "dbName")]
44 pub db_name: Option<String>,
45}
46
47#[derive(Debug, Clone, Deserialize, Serialize)]
48pub struct Datamodel {
49 pub models: Vec<Model>,
50 pub enums: Vec<DatamodelEnum>,
51 #[serde(rename = "types")]
52 pub type_models: Vec<Model>,
53 pub indexes: Vec<Index>,
54}
55
56#[derive(Debug, Clone, Deserialize, Serialize)]
57pub struct UniqueIndex {
58 pub name: String,
59 pub fields: Vec<String>,
60}
61
62#[derive(Debug, Clone, Deserialize, Serialize)]
63pub struct PrimaryKey {
64 pub name: Option<String>,
65 pub fields: Vec<String>,
66}
67
68#[derive(Debug, Clone, Deserialize, Serialize)]
69#[serde(rename_all = "camelCase")]
70pub struct Model {
71 pub name: String,
72 pub db_name: Option<String>,
73 pub schema: Option<String>,
74 pub fields: Vec<Field>,
75 pub unique_fields: Vec<Vec<String>>,
76 pub unique_indexes: Vec<UniqueIndex>,
77 pub documentation: Option<String>,
78 pub primary_key: Option<PrimaryKey>,
79 pub is_generated: Option<bool>,
80}
81
82#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
83#[serde(rename_all = "lowercase")]
84pub enum FieldKind {
85 Scalar,
86 Object,
87 Enum,
88 Unsupported,
89}
90
91#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
92#[serde(rename_all = "lowercase")]
93pub enum FieldNamespace {
94 Model,
95 Prisma,
96}
97
98#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
99#[serde(rename_all = "camelCase")]
100pub enum FieldLocation {
101 Scalar,
102 InputObjectTypes,
103 OutputObjectTypes,
104 EnumTypes,
105 FieldRefTypes,
106}
107
108impl AsRef<str> for FieldLocation {
109 fn as_ref(&self) -> &str {
110 match self {
111 FieldLocation::Scalar => "scalar",
112 FieldLocation::InputObjectTypes => "inputObjectTypes",
113 FieldLocation::OutputObjectTypes => "outputObjectTypes",
114 FieldLocation::EnumTypes => "enumTypes",
115 FieldLocation::FieldRefTypes => "fieldRefTypes",
116 }
117 }
118}
119
120#[derive(Debug, Clone, Deserialize, Serialize)]
121#[serde(rename_all = "camelCase")]
122pub struct Field {
123 pub kind: FieldKind,
124 pub name: String,
125 pub is_required: bool,
126 pub is_list: bool,
127 pub is_unique: bool,
128 pub is_id: bool,
129 pub is_read_only: bool,
130 pub is_generated: Option<bool>,
131 pub is_updated_at: Option<bool>,
132 #[serde(rename = "type")]
133 pub field_type: String,
134 pub native_type: Option<Vec<Value>>,
136 pub db_name: Option<String>,
137 pub has_default_value: bool,
138 #[serde(rename = "default")]
139 pub default_value: Option<FieldDefaultValue>,
140 pub relation_from_fields: Option<Vec<String>>,
141 pub relation_to_fields: Option<Vec<String>>,
142 pub relation_on_delete: Option<String>,
143 pub relation_on_update: Option<String>,
144 pub relation_name: Option<String>,
145 pub documentation: Option<String>,
146}
147
148#[derive(Debug, Clone, Deserialize, Serialize)]
149#[serde(untagged)]
150pub enum FieldDefaultValue {
151 Object(FieldDefault),
152 Scalar(FieldDefaultScalar),
153 ScalarList(Vec<FieldDefaultScalar>),
154}
155
156#[derive(Debug, Clone, Deserialize, Serialize)]
157pub struct FieldDefault {
158 pub name: String,
159 pub args: Vec<Value>,
161}
162
163pub type FieldDefaultScalar = Value;
165
166#[derive(Debug, Clone, Deserialize, Serialize)]
167#[serde(rename_all = "camelCase")]
168pub struct Index {
169 pub model: String,
170 #[serde(rename = "type")]
171 pub index_type: IndexType,
172 pub is_defined_on_field: bool,
173 pub name: Option<String>,
174 pub db_name: Option<String>,
175 pub algorithm: Option<String>,
176 pub clustered: Option<bool>,
177 pub fields: Vec<IndexField>,
178}
179
180#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
181#[serde(rename_all = "lowercase")]
182pub enum IndexType {
183 Id,
184 Normal,
185 Unique,
186 Fulltext,
187}
188
189#[derive(Debug, Clone, Deserialize, Serialize)]
190#[serde(rename_all = "camelCase")]
191pub struct IndexField {
192 pub name: String,
193 pub sort_order: Option<SortOrder>,
194 pub length: Option<u32>,
195 pub operator_class: Option<String>,
196}
197
198#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
199#[serde(rename_all = "lowercase")]
200pub enum SortOrder {
201 Asc,
202 Desc,
203}
204
205#[derive(Debug, Clone, Deserialize, Serialize)]
206#[serde(rename_all = "camelCase")]
207pub struct Schema {
208 pub root_query_type: Option<String>,
209 pub root_mutation_type: Option<String>,
210 pub input_object_types: InputObjectTypes,
211 pub output_object_types: OutputObjectTypes,
212 pub enum_types: EnumTypes,
213 pub field_ref_types: FieldRefTypes,
214}
215
216#[derive(Debug, Clone, Deserialize, Serialize)]
217pub struct InputObjectTypes {
218 pub model: Option<Vec<InputType>>,
219 pub prisma: Vec<InputType>,
220}
221
222#[derive(Debug, Clone, Deserialize, Serialize)]
223pub struct OutputObjectTypes {
224 pub model: Vec<OutputType>,
225 pub prisma: Vec<OutputType>,
226}
227
228#[derive(Debug, Clone, Deserialize, Serialize)]
229pub struct EnumTypes {
230 pub model: Option<Vec<SchemaEnum>>,
231 pub prisma: Vec<SchemaEnum>,
232}
233
234#[derive(Debug, Clone, Deserialize, Serialize)]
235pub struct FieldRefTypes {
236 pub prisma: Option<Vec<FieldRefType>>,
237}
238
239#[derive(Debug, Clone, Deserialize, Serialize)]
240pub struct Query {
241 pub name: String,
242 pub args: Vec<SchemaArg>,
243 pub output: QueryOutput,
244}
245
246#[derive(Debug, Clone, Deserialize, Serialize)]
247#[serde(rename_all = "camelCase")]
248pub struct QueryOutput {
249 pub name: String,
250 pub is_required: bool,
251 pub is_list: bool,
252}
253
254#[derive(Debug, Clone, Deserialize, Serialize)]
255#[serde(rename_all = "camelCase")]
256pub struct TypeRef<T: AsRef<str>> {
257 pub is_list: bool,
258 #[serde(rename = "type")]
259 pub type_name: String,
260 pub location: T,
261 pub namespace: Option<FieldNamespace>,
262}
263
264pub type InputTypeRef = TypeRef<FieldLocation>;
265
266#[derive(Debug, Clone, Deserialize, Serialize)]
267#[serde(rename_all = "camelCase")]
268pub struct SchemaArg {
269 pub name: String,
270 pub comment: Option<String>,
271 pub is_nullable: bool,
272 pub is_required: bool,
273 pub input_types: Vec<InputTypeRef>,
274 pub deprecation: Option<Deprecation>,
275}
276
277#[derive(Debug, Clone, Deserialize, Serialize)]
278pub struct OutputType {
279 pub name: String,
280 pub fields: Vec<SchemaField>,
281}
282
283#[derive(Debug, Clone, Deserialize, Serialize)]
284#[serde(rename_all = "camelCase")]
285pub struct SchemaField {
286 pub name: String,
287 pub is_nullable: Option<bool>,
288 pub output_type: OutputTypeRef,
289 pub args: Vec<SchemaArg>,
290 pub deprecation: Option<Deprecation>,
291 pub documentation: Option<String>,
292}
293
294#[derive(Debug, Clone, Deserialize, Serialize)]
295#[serde(rename_all = "camelCase")]
296pub struct OutputTypeRef {
297 pub is_list: bool,
298 #[serde(rename = "type")]
299 pub type_name: String,
300 pub location: FieldLocation,
301}
302
303#[derive(Debug, Clone, Deserialize, Serialize)]
304#[serde(rename_all = "camelCase")]
305pub struct Deprecation {
306 pub since_version: String,
307 pub reason: String,
308 pub planned_removal_version: Option<String>,
309}
310
311#[derive(Debug, Clone, Deserialize, Serialize)]
312pub struct InputType {
313 pub name: String,
314 pub constraints: InputTypeConstraints,
315 pub meta: Option<InputTypeMeta>,
316 pub fields: Vec<SchemaArg>,
317}
318
319#[derive(Debug, Clone, Deserialize, Serialize)]
320#[serde(rename_all = "camelCase")]
321pub struct InputTypeConstraints {
322 pub max_num_fields: Option<u32>,
323 pub min_num_fields: Option<u32>,
324 pub fields: Option<Vec<String>>,
325}
326
327#[derive(Debug, Clone, Deserialize, Serialize)]
328pub struct InputTypeMeta {
329 pub source: Option<String>,
330 pub grouping: Option<String>,
331}
332
333#[derive(Debug, Clone, Deserialize, Serialize)]
334#[serde(rename_all = "camelCase")]
335pub struct FieldRefType {
336 pub name: String,
337 pub allow_types: Vec<TypeRef<FieldLocation>>,
338 pub fields: Vec<SchemaArg>,
339}
340
341#[derive(Debug, Clone, Deserialize, Serialize)]
342#[serde(rename_all = "camelCase")]
343pub struct ModelMapping {
344 pub model: String,
345 pub plural: Option<String>,
347 pub find_unique: Option<String>,
348 pub find_unique_or_throw: Option<String>,
349 pub find_first: Option<String>,
350 pub find_first_or_throw: Option<String>,
351 pub find_many: Option<String>,
352 pub create: Option<String>,
353 pub create_many: Option<String>,
354 pub create_many_and_return: Option<String>,
355 pub update: Option<String>,
356 pub update_many: Option<String>,
357 pub update_many_and_return: Option<String>,
358 pub upsert: Option<String>,
359 pub delete: Option<String>,
360 pub delete_many: Option<String>,
361 pub aggregate: Option<String>,
362 pub group_by: Option<String>,
363 pub count: Option<String>,
364 pub find_raw: Option<String>,
365 pub aggregate_raw: Option<String>,
366}
367
368#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
369#[serde(rename_all = "camelCase")]
370pub enum ModelAction {
371 FindUnique,
372 FindUniqueOrThrow,
373 FindFirst,
374 FindFirstOrThrow,
375 FindMany,
376 Create,
377 CreateMany,
378 CreateManyAndReturn,
379 Update,
380 UpdateMany,
381 UpdateManyAndReturn,
382 Upsert,
383 Delete,
384 DeleteMany,
385 GroupBy,
386 Count,
388 Aggregate,
389 FindRaw,
390 AggregateRaw,
391}
392
393impl From<&Field> for String {
394 fn from(field: &Field) -> Self {
395 let field_name = field
397 .name
398 .clone()
399 .chars()
400 .fold(String::new(), |mut acc, c| {
401 if c.is_uppercase() {
402 if !acc.is_empty() {
403 acc.push('_');
404 }
405 acc.push(c.to_ascii_lowercase());
406 } else {
407 acc.push(c);
408 }
409 acc
410 });
411 let mut field_type = String::new();
412 let t = match field.field_type.as_str() {
413 "String" => "String".to_string(),
414 "Int" => "i32".to_string(),
415 "Float" => "f64".to_string(),
416 "Boolean" => "bool".to_string(),
417 "DateTime" => "chrono::NaiveDateTime".to_string(),
418 _ => field.field_type.clone(),
419 };
420
421 if !field.is_required {
422 field_type.push_str("Option<");
423 }
424 if field.is_list {
425 field_type.push_str("Vec<");
426 }
427
428 field_type.push_str(&t);
429
430 if field.is_list {
431 field_type.push('>');
432 }
433 if !field.is_required {
434 field_type.push('>');
435 }
436
437 format!("{:>4}pub {}: {},\n", "", field_name, field_type)
438 }
439}