taitan_orm_parser/field_mapper/
field_mapper.rs

1use 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        // panic!("{:?}", fields);
155        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_marks_indexed<'a, T>(&self, fields: T, db_type: &DatabaseType) -> TokenStream
237    // where
238    //     T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,{
239    //     self.marks_mapper
240    //         .connect_indexed(fields, self.get_escaper(db_type))
241    // }
242
243    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_sets_indexed<'a, T>(&self, fields: T, db_type: &DatabaseType) -> TokenStream
256    // where
257    //     T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
258    // {
259    //     self.sets_mapper
260    //         .connect_indexed(fields, self.get_escaper(db_type))
261    // }
262
263    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    // pub fn gen_conditions_indexed<'a, T>(&self, fields: T, db_type: &DatabaseType) -> TokenStream
279    // where
280    //     T: IntoIterator<Item = &'a FieldDef<'a>> + Clone,
281    // {
282    //     self.conditions_mapper
283    //         .connect_dynamic_indexed(fields, self.get_escaper(db_type))
284    // }
285}