1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
extern crate proc_macro;
use proc_macro2::{Ident, Span};
use quote::quote;
use quote::ToTokens;
use syn;
use crate::proc_macro::TokenStream;
#[proc_macro_derive(CRUDEnable)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap();
impl_macro(&ast)
}
fn find_id_type_ident(arg: &syn::Data) -> Ident {
let mut id_type = Ident::new("String", Span::call_site());
match &arg {
syn::Data::Struct(ref data_struct) => match data_struct.fields {
syn::Fields::Named(ref fields_named) => {
for (_, field) in fields_named.named.iter().enumerate() {
let field_name = format!("{}", field.ident.to_token_stream());
if field_name.eq("id") {
let ty = format!("{}", field.ty.to_token_stream());
let mut inner_type = ty.trim().replace(" ", "").to_string();
if inner_type.starts_with("Option<") {
inner_type = inner_type.trim_start_matches("Option<").trim_end_matches(">").to_string();
}
id_type = Ident::new(inner_type.as_str(), Span::call_site());
break;
}
}
}
syn::Fields::Unnamed(_) => {}
syn::Fields::Unit => {}
},
_ => (),
}
id_type
}
fn impl_macro(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let id_type = find_id_type_ident(&ast.data);
let gen = quote! {
impl CRUDEnable for #name {
type IdType = #id_type;
fn table_name() -> String {
let mut name = stringify!(#name).to_string();
let names: Vec<&str> = name.split("::").collect();
name = names.get(names.len() - 1).unwrap().to_string();
return rbatis::utils::string_util::to_snake_name(&name);
}
}
};
gen.into()
}