mydb_macros/derives/
utils.rs1use proc_macro2::{TokenTree, Ident, Span, TokenStream};
2use syn::{
3 Attribute, Data, Fields, Field, GenericArgument, Meta, PathArguments, Type, TypePath
4};
5use quote::quote;
6
7use crate::derives::entity::{ TableField, MyField };
8
9pub fn get_table_list(data: Data) -> Vec<TableField> {
10 let mut table_list: Vec<TableField> = vec![];
11 match data {
12 Data::Struct(data_struct) => {
13 match data_struct.fields {
14 Fields::Named(fields) => {
15 for field in fields.named {
16 let name = get_field_name(&field);
17 let mut field_type = TokenStream::new();
18 let mut field_span = "".to_string();
19 let mut my_field: MyField = MyField::new();
20 let mut exist = true;
21
22 field.attrs.iter()
23 .filter(| attr | attr.path().is_ident("table_field"))
24 .for_each(|attr| {
25
26 if let Meta::List(lits) = &attr.meta {
27 let mut table_field_content = format!("");
28 let _ = &lits.tokens.clone().into_iter().for_each(| ts | {
29 table_field_content += &ts.span().source_text().unwrap_or(format!(""));
30 });
31 table_field_content = table_field_content.replace(" ", "");
32 let exist_vec: &Vec<&str> = &table_field_content.split(',').collect();
33 if exist_vec.contains(&"exist=false") {
34 exist = false;
35 }
36 }
37 });
38
39 if let Type::Path(_ty) = &field.ty {
40 my_field = recursive_print_ident(_ty);
41 field_type = my_field_ts(my_field.clone());
42 field_span = my_field_span(my_field.clone());
43 }
44 table_list.push( TableField {
45 name,
46 field_type,
47 exist,
48 my_field,
49 field_span,
50 })
51 }
52 },
53 _ => ()
54 }
55 },
56 _ => ()
57 }
58 table_list
59}
60
61pub fn get_field_name(field: &Field) -> String {
62 if let Some(ident) = &field.ident {
63 if let Some(text) = ident.span().source_text() {
64 return text;
65 }
66 }
67 format!("")
68}
69
70pub fn get_table_name(attrs: Vec<Attribute>) -> String {
71 let mut table_name = format!("");
72 attrs
73 .iter()
74 .filter(|attr| attr.path().is_ident("mydb"))
75 .into_iter()
76 .for_each(| attr | {
77 if let Meta::List(lits) = &attr.meta {
78 let _ = &lits.tokens.clone().into_iter().for_each(| ts | {
79 if let TokenTree::Literal(l_name) = ts {
80 if l_name.to_string().len() > 0 {
81 table_name = l_name.to_string().replace('"', "");
82 } else {
83 eprintln!("no setting table_name")
84 }
85 }
86 });
87 }
88 });
89 table_name
90}
91
92pub fn set_ident(name: &String) -> Ident {
93 Ident::new(&name, Span::call_site())
94}
95
96pub fn recursive_print_ident(type_path: &TypePath) -> MyField {
97 let mut my_field: MyField = MyField::new();
98 for segment in &type_path.path.segments {
99 my_field.field_type = Some(segment.ident.clone());
100 match &segment.arguments {
101 PathArguments::AngleBracketed(args) => {
102 my_field.lt = Some("<".to_string());
103 for arg in &args.args {
104 if let GenericArgument::Type(ty) = arg {
105 if let Type::Path(inner_path) = ty {
106 my_field.children = Some(Box::new(recursive_print_ident(inner_path)));
107 }
108 }
109 }
110 my_field.gt = Some(">".to_string());
111 }
112 _ => {}
113 }
114 }
115 my_field
116}
117
118pub fn my_field_ts(my_field: MyField) -> TokenStream {
119 let mut ts: Vec<TokenStream> = Vec::new();
120
121 match my_field.field_type {
122 Some(_field_type) => ts.push(quote!(#_field_type)),
123 None => (),
124 };
125
126 match my_field.lt {
127 Some(_) => ts.push(quote!(<)),
128 None => (),
129 };
130
131 match my_field.children {
132 Some(children) => {
133 let text = my_field_ts(*children);
134 ts.push(text)
135 },
136 None => (),
137 };
138
139 match my_field.gt {
140 Some(_) => ts.push(quote!(>)),
141 None => (),
142 };
143
144 quote!{ #(#ts)* }
145}
146
147
148pub fn my_field_span(my_field: MyField) -> String {
149 let mut s = "".to_string();
150
151 match my_field.field_type {
152 Some(field_type) => s += &field_type.to_string(),
153 None => (),
154 };
155
156 match my_field.lt {
157 Some(_) => s += "<",
158 None => (),
159 };
160
161 match my_field.children {
162 Some(children) => {
163 s += &my_field_span(*children);
164 },
165 None => (),
166 };
167
168
169 match my_field.gt {
170 Some(_) => s += ">",
171 None => (),
172 };
173
174 s
175}