taitan_orm_parser/field_mapper/
field_mapper.rs1use super::base::{
2 KeywordsEscaper, MySqlKeywordEscaper, PostgresKeywordEscaper, SqliteKeywordEscaper,
3};
4use super::mappers::{ArgsMapper, ConditionsMapper, MarksMapper, NamesMapper, RowMapper, SetsMapper, UpsertSetsMapper};
5use crate::field_mapper::base::Connector2;
6use crate::{DatabaseType, FieldName, FieldTokenType};
7use crate::FieldDef;
8use proc_macro2::{Ident, TokenStream};
9use quote::{format_ident, quote};
10use std::borrow::Cow;
11use case::CaseExt;
12use crate::FieldTokenType::{InnerMostType, InnerVariantExpr};
13
14#[derive(Clone, Debug, Default)]
15pub struct FieldMapper {
16 names_mapper: NamesMapper,
17 marks_mapper: MarksMapper,
18 sets_mapper: SetsMapper,
19 conditions_mapper: ConditionsMapper,
20 upsert_sets_mapper: UpsertSetsMapper,
21 args_mapper: ArgsMapper,
22 row_mapper: RowMapper,
23 mysql_escaper: MySqlKeywordEscaper,
24 postgres_escaper: PostgresKeywordEscaper,
25 sqlite_escaper: SqliteKeywordEscaper,
26}
27
28fn generate_nested_vec<'a>(input: Vec<&'a FieldDef<'a>>) -> Vec<Vec<&'a FieldDef<'a>>> {
29 input.iter().enumerate().fold(Vec::new(), |mut acc, (i, _)| {
30 acc.push(input[..=i].to_vec());
31 acc
32 })
33}
34
35impl FieldMapper {
36 pub fn new() -> Self {
37 Self::default()
38 }
39
40 fn get_escaper(&self, db_type: &DatabaseType) -> &dyn KeywordsEscaper {
41 match db_type {
42 DatabaseType::MySql => &self.mysql_escaper,
43 DatabaseType::Postgres => &self.postgres_escaper,
44 DatabaseType::Sqlite => &self.sqlite_escaper,
45 }
46 }
47
48 pub fn escape<'a>(&'a self, word: &'a str, db_type: &DatabaseType) -> Cow<'a, str> {
49 self.get_escaper(db_type).escape(word)
50 }
51
52 pub fn gen_add_to_args<'a, T>(&self, fields: T) -> TokenStream
53 where
54 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
55 {
56 let streams = fields
57 .into_iter()
58 .map(|def| self.args_mapper.map_add_to_args(def))
59 .collect::<Vec<_>>();
60 quote! {
61 #( #streams; )*
62 }
63 }
64
65 pub fn gen_enum_add_to_args<'a, T>(&self, fields: T) -> TokenStream
66 where
67 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
68 {
69 let streams = fields
70 .into_iter()
71 .map(|def| self.args_mapper.map_enum_add_to_args(def))
72 .collect::<Vec<_>>();
73 quote! {
74 #( #streams; )*
75 }
76 }
77
78 pub fn gen_template_add_to_args<'a, T>(&self, fields: T) -> TokenStream
79 where
80 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
81 {
82 let streams = fields
83 .into_iter()
84 .map(|def|
85 {
86 let field_name = def.struct_field.name.get_name();
87 let s = self.args_mapper.map_add_to_args(def);
88 quote! {
89 #field_name => #s,
90 }
91 }
92 )
93 .collect::<Vec<_>>();
94 quote! {
95 match name {
96 #( #streams )*
97 _=> unreachable!(),
98 }
99 }
100 }
101
102 pub fn gen_row_try_get<'a, T>(&self, fields: T) -> TokenStream
103 where
104 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
105 {
106 let streams = fields
107 .into_iter()
108 .map(|def| self.row_mapper.map_row_try_get(def))
109 .collect::<Vec<_>>();
110 quote! {
111 #( #streams )*
112 }
113 }
114
115 pub fn gen_struct_fields<'a, T>(&self, fields: T, force_to_option: bool) -> TokenStream
116 where
117 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
118 {
119 let field_token_type = if force_to_option {
120 FieldTokenType::NestedOptionType
121 } else {
122 FieldTokenType::InnerMostType
123 };
124 let streams = fields
125 .into_iter()
126 .map(|def|
127
128 def.struct_field.to_token_stream(field_token_type))
129 .collect::<Vec<_>>();
130 quote! {
131 #( #streams,)*
132 }
133 }
134
135 pub fn gen_enum_expr_variants<'a, T>(&self, fields: T) -> TokenStream
136 where
137 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
138 {
139 let streams = fields
140 .into_iter()
141 .map(|def| def.struct_field.to_token_stream(FieldTokenType::VariantExpr))
142 .collect::<Vec<_>>();
143 quote! {
144 #( #streams,)*
145 }
146 }
147
148 pub fn gen_enum_variants<'a, T>(&self, fields: T) -> TokenStream
149 where
150 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
151 {
152 let mut streams :TokenStream = TokenStream::new();
153 let fields: Vec<&FieldDef> = fields.into_iter().collect();
154 let groups = generate_nested_vec(fields.clone());
156
157 for group in groups {
158 let name:String = group.iter().map(|def| {def.struct_field.name.get_name().to_camel()}).collect();
159 let variant_name = format_ident!("{}", name);
160 let stream = group
161 .iter()
162 .map(|def| def.struct_field.to_token_stream(InnerVariantExpr))
163 .collect::<Vec<_>>();
164 streams.extend(quote! {
165 #variant_name{ #( #stream, )* },
166 })
167 }
168 streams
169 }
170
171
172
173 pub fn gen_selected_default<'a, T>(&self, fields: T) -> TokenStream
174 where
175 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
176 {
177 let streams = fields
178 .into_iter()
179 .map(|def| self.row_mapper.map_selected_default(def))
180 .collect::<Vec<_>>();
181 quote! {
182 #( #streams )*
183 }
184 }
185
186 pub fn gen_names<'a, T>(&self, fields: T, db_type: &DatabaseType) -> TokenStream
187 where
188 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
189 {
190 self.names_mapper
191 ._connect(fields, self.get_escaper(db_type))
192 }
193
194 pub fn gen_idents<'a, T>(&self, fields: T) -> TokenStream
195 where
196 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
197 {
198 let mut idents: Vec<Ident> = Vec::new();
199 for field in fields.into_iter() {
200 match &field.struct_field.name {
201 FieldName::Named(named)=> {
202 idents.push(format_ident!("{}", named));
203 }
204 FieldName::Unnamed {idx, name}=> {
205 idents.push(format_ident!("e{}", idx));
206 }
207 }
208 }
209 quote! {
210 #( #idents, )*
211 }
212 }
213
214 pub fn gen_upsert_sets<'a, T>(&self, fields: T, db_type: &DatabaseType) -> TokenStream
215 where
216 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
217 {
218 self.upsert_sets_mapper
219 ._connect(fields, self.get_escaper(db_type))
220 }
221
222 pub fn gen_marks<'a, T>(&self, fields: T, db_type: &DatabaseType) -> TokenStream
223 where
224 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
225 {
226 match db_type {
227 DatabaseType::Postgres => self
228 .marks_mapper
229 ._connect_indexed(fields, self.get_escaper(db_type)),
230 _ => self
231 .marks_mapper
232 ._connect(fields, self.get_escaper(db_type)),
233 }
234 }
235
236 pub fn gen_sets<'a, T>(&self, fields: T, db_type: &DatabaseType) -> TokenStream
244 where
245 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
246 {
247 match db_type {
248 DatabaseType::Postgres => self.sets_mapper._connect_indexed(fields, self.get_escaper(db_type)),
249 _ => self
250 .sets_mapper
251 ._connect(fields, self.get_escaper(db_type)),
252 }
253 }
254
255 pub fn gen_conditions<'a, T>(&self, fields: T, db_type: &DatabaseType, is_enum: bool) -> TokenStream
264 where
265 T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
266 {
267 match db_type {
268 DatabaseType::Postgres => {
269 self.conditions_mapper
270 ._connect_expr(fields, self.get_escaper(db_type), true, is_enum)
271 }
272 _ => self
273 .conditions_mapper
274 ._connect_expr(fields, self.get_escaper(db_type), false, is_enum),
275 }
276 }
277
278 }