massbit_sol/generator/graphql.rs
1use crate::generator::Generator;
2use crate::schema::{Schema, Variant};
3use lazy_static::lazy_static;
4use std::collections::{BTreeMap, HashMap};
5use std::fmt::Write;
6
7lazy_static! {
8 // https://www.codingame.com/playgrounds/365/getting-started-with-rust/primitive-data-types
9 // pub static ref PRIMITIVE_DATA_TYPES: Vec<&'static str> = vec![
10 // "bool", "char", "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "isize", "usize", "f32",
11 // "f64", "str", //Not support yet
12 // "NonZeroU8", "NonZeroU32", "NonZeroU64", "NonZeroU128",
13 // "NonZeroI8", "NonZeroI32", "NonZeroI64", "NonZeroI128",
14 // "array", "slice", "tuple",
15 // ];
16
17 // https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html
18 pub static ref MAPPING_RUST_TYPES_TO_DB: HashMap<&'static str, &'static str> = HashMap::from([
19 ("bool", "Bool"),
20 //The graph generator postgres sql only handles with bigint
21 ("i8", "BigInt"),
22 ("u8", "BigInt"),
23 ("i16", "BigInt"),
24 ("u16", "BigInt"),
25 ("NonZeroU8", "BigInt"),
26 ("NonZeroU16", "BigInt"),
27 ("NonZeroI8", "BigInt"),
28 ("NonZeroI16", "BigInt"),
29
30 ("i32", "Integer"),
31 ("u32", "Integer"),
32 ("NonZeroI32", "Integer"),
33 ("NonZeroU32", "Integer"),
34
35
36 ("i64", "BigInt"),
37 ("u64", "BigInt"),
38 ("isize", "BigInt"),
39 ("usize", "BigInt"),
40 ("usize", "BigInt"),
41 ("NonZeroU64", "BigInt"),
42 ("NonZeroU128", "BigInt"),
43 ("NonZeroUsize", "BigInt"),
44 ("NonZeroI64", "BigInt"),
45 ("NonZeroI128", "BigInt"),
46 ("NonZeroIsize", "BigInt"),
47
48 ("f32", "Float"),
49
50 ("f64", "Double"),
51
52 ("str", "String"),
53 ("String", "String"),
54 ("char", "String"),
55 ]);
56 pub static ref MAPPING_DB_TYPES_TO_RUST: HashMap<&'static str, &'static str> = HashMap::from([
57 ("Bool", "bool"),
58
59 ("SmallInt", "i64"),
60 ("Integer", "i64"),
61 ("BigInt", "i64"),
62
63 ("Float", "f32"),
64
65 ("Double", "f64"),
66
67 ("String", "String"),
68 ]);
69
70 pub static ref DEFAULT_TYPE_DB : &'static str = "String";
71}
72
73impl<'a> Generator<'a> {
74 pub fn generate_graphql_schema(&self, schema: &Schema) -> String {
75 let mut out = String::new();
76 if let Some(variants) = &schema.variants {
77 // List instruction
78 for variant in variants {
79 // Write table if there is inner_type
80 let variant_entity = self.generate_variant_entity(variant, &self.definitions);
81 let _ = writeln!(out, "{}", &variant_entity);
82 // Get definitions
83 // if let Some(sub_schema) = self.definitions.get(&inner_type) {
84 // // get a table corresponding to sub_schema
85 // let str_entity: String =
86 // Schema::gen_entity_db(sub_schema, inner_type, instruction.name);
87 // writeln!(out, "{}", str_entity);
88 // } else if MAPPING_RUST_TYPES_TO_DB.contains_key(inner_type.as_str()) {
89 // let str_entity: String =
90 // Schema::gen_entity_db(&Schema::default(), inner_type, instruction.name);
91 // writeln!(out, "{}", str_entity);
92 // }
93 }
94 }
95 out
96 }
97 fn generate_variant_entity(
98 &self,
99 variant: &Variant,
100 definitions: &BTreeMap<String, Schema>,
101 ) -> String {
102 let mut entity_properties: Vec<String> = vec![String::from("id: ID!")];
103 //Account assigment
104 if let Some(accounts) = &variant.accounts {
105 for account in accounts {
106 entity_properties.push(format!("\t{}: String", account.name));
107 }
108 }
109 if let Some(inner_type) = &variant.inner_type {
110 if let Some(def) = definitions.get(inner_type.as_str()) {
111 if let Some(properties) = &def.properties {
112 for property in properties {
113 let db_type = MAPPING_RUST_TYPES_TO_DB
114 .get(property.data_type.as_str())
115 .unwrap_or(&*DEFAULT_TYPE_DB);
116 if property.array_length.is_some() {
117 entity_properties.push(format!("\t{}: [{}]", &property.name, db_type));
118 } else {
119 entity_properties.push(format!("\t{}: {}", &property.name, db_type));
120 }
121 }
122 }
123 } else if let Some(db_type) = MAPPING_RUST_TYPES_TO_DB.get(inner_type.as_str()) {
124 //Inner type is primitive. Store is as an value field
125 entity_properties.push(format!("\tvalue: {}", db_type));
126 }
127 }
128 format!(
129 r#"type {} @entity {{
130 {entity_properties}
131}}"#,
132 &variant.name,
133 entity_properties = entity_properties.join(",\n")
134 )
135 }
136 // pub fn gen_entity_db(schema: &Schema, entity_type: String, entity_name: String) -> String {
137 // let mut entity_properties: Vec<String> = vec![String::from("\tid: ID!")];
138 // match MAPPING_RUST_TYPES_TO_DB.get(entity_type.as_str()) {
139 // Some(db_type) => {
140 // entity_properties.push(format!("\tvalue: {}", db_type));
141 // }
142 // None => {
143 // if let Some(properties) = &schema.properties {
144 // for property in properties {
145 // match property.array_length {
146 // Some(_array_length) => {
147 // let db_type = MAPPING_RUST_TYPES_TO_DB
148 // .get(property.data_type.as_str())
149 // .unwrap_or(&*DEFAULT_TYPE_DB);
150 // entity_properties
151 // .push(format!("\t{}: [{}]", &property.name, db_type));
152 // }
153 // None => {
154 // let db_type = MAPPING_RUST_TYPES_TO_DB
155 // .get(property.data_type.as_str())
156 // .unwrap_or(&*DEFAULT_TYPE_DB);
157 // entity_properties
158 // .push(format!("\t{}: {}", &property.name, db_type));
159 // }
160 // }
161 // }
162 // }
163 // }
164 // };
165 // format!(
166 // r#"type {} @entity {{
167 // {entity_properties}
168 // }}"#,
169 // &entity_name,
170 // entity_properties = entity_properties.join(",\n")
171 // )
172 // }
173}