mybatis_macro/
lib.rs

1#![allow(unused_assignments)]
2extern crate proc_macro;
3
4use syn::{parse_macro_input, AttributeArgs, DataStruct, ItemFn};
5
6use crate::macros::mybatis_html_impl::impl_macro_mybatis_html;
7use crate::macros::mybatis_plus_impl::{impl_mybatis_plus, impl_mybatis_plus_driver};
8use crate::macros::mybatis_sql_impl::impl_macro_mybatis_sql;
9use crate::macros::py_sql_impl::impl_macro_py_sql;
10use crate::proc_macro::TokenStream;
11
12mod element_from;
13mod func;
14mod html_loader;
15mod parser;
16mod py_sql;
17mod string_util;
18use std::collections::HashMap;
19
20mod macros;
21mod util;
22
23#[proc_macro_derive(MybatisPlus)]
24pub fn macro_derive(input: TokenStream) -> TokenStream {
25    let ast = syn::parse(input).unwrap();
26    let stream = impl_mybatis_plus_driver(&ast, "", "", &HashMap::new());
27    #[cfg(feature = "debug_mode")]
28    {
29        println!("............gen impl MybatisPlus:\n {}", stream);
30        println!("............gen impl MybatisPlus end............");
31    }
32
33    stream
34}
35
36/// auto create sql macro,this macro use Mybatis.fetch_prepare and Mybatis.exec_prepare
37/// for example:
38///     pub static Mybatis:Lazy<Mybatis> = Lazy::new(||Mybatis::new());
39///     #[mybatis_sql(Mybatis, "select * from biz_activity where id = ?")]
40///     async fn select(name: &str) -> BizActivity {}
41///
42/// or:
43///     #[mybatis_sql("select * from biz_activity where id = ?")]
44///     async fn select(mybatis:&Mybatis, name: &str) -> BizActivity {}
45///
46#[proc_macro_attribute]
47pub fn mybatis_sql(args: TokenStream, func: TokenStream) -> TokenStream {
48    let args = parse_macro_input!(args as AttributeArgs);
49    let target_fn: ItemFn = syn::parse(func).unwrap();
50    let stream = impl_macro_mybatis_sql(&target_fn, &args);
51    #[cfg(feature = "debug_mode")]
52    {
53        println!("............gen macro sql:\n {}", stream);
54        println!("............gen macro sql end............");
55    }
56
57    stream
58}
59
60/// py sql create macro,this macro use RB.py_fetch and RB.py_exec
61///
62///  pub static RB:Lazy<Mybatis> = Lazy::new(||Mybatis::new());
63///  #[py_sql(RB,"select * from biz_activity where delete_flag = 0")]
64///  async fn py_select_page(page_req: &PageRequest, name: &str) -> Page<BizActivity> { }
65///  or:
66///  #[py_sql("select * from biz_activity where delete_flag = 0")]
67///  async fn py_select_page(mybatis: &mut MybatisExecutor<'_,'_>, page_req: &PageRequest, name: &str) -> Page<BizActivity> { }
68///
69///  or more example:
70///  #[py_sql("
71///     SELECT * FROM biz_activity
72///     if  name != null:
73///       AND delete_flag = #{del}
74///       AND version = 1
75///       if  age!=1:
76///         AND version = 1
77///       AND version = 1
78///     AND a = 0
79///       AND version = 1
80///     and id in (
81///     trim ',': for item in ids:
82///       #{item},
83///     )
84///     and id in (
85///     trim ',': for index,item in ids:
86///       #{item},
87///     )
88///     trim 'AND':
89///       AND delete_flag = #{del2}
90///     choose:
91///         when age==27:
92///           AND age = 27
93///         otherwise:
94///           AND age = 0
95///     WHERE id  = '2'")]
96///   pub async fn py_select_mybatis(mybatis: &Mybatis, name: &str) -> Option<BizActivity> {}
97#[proc_macro_attribute]
98pub fn py_sql(args: TokenStream, func: TokenStream) -> TokenStream {
99    let args = parse_macro_input!(args as AttributeArgs);
100    let target_fn: ItemFn = syn::parse(func).unwrap();
101    let stream = impl_macro_py_sql(&target_fn, &args);
102    #[cfg(feature = "debug_mode")]
103    {
104        println!("............gen macro py_sql :\n {}", stream);
105        println!("............gen macro py_sql end............");
106    }
107    stream
108}
109
110/// html sql create macro,this macro use RB.py_fetch and RB.py_exec
111/// for example:
112///
113/// pub static RB:Lazy<Mybatis> = Lazy::new(||Mybatis::new());
114/// #[mybatis_html(RB,"example/example.html")]
115/// pub async fn py_select_mybatis(name: &str) -> Option<BizActivity> {}
116///
117/// or:
118///
119/// #[mybatis_html("example/example.html")]
120/// pub async fn py_select_mybatis(mybatis: &Mybatis, name: &str) -> Option<BizActivity> {}
121///
122#[proc_macro_attribute]
123pub fn mybatis_html(args: TokenStream, func: TokenStream) -> TokenStream {
124    let args = parse_macro_input!(args as AttributeArgs);
125    let target_fn: ItemFn = syn::parse(func).unwrap();
126    let stream = impl_macro_mybatis_html(&target_fn, &args);
127    #[cfg(feature = "debug_mode")]
128    {
129        println!("............gen macro html_sql :\n {}", stream);
130        println!("............gen macro html_sql end............");
131    }
132    stream
133}
134
135/// Mybatis Plus,You can define functionality using the following properties
136/// #[mybatis_plus]
137/// #[mybatis_plus(table_name:"biz_activity")]
138/// #[mybatis_plus(table_name:"biz_activity" | table_columns:"id,name,version,delete_flag" | formats_pg:"id:{}::uuid,name:{}::string")]
139/// pub struct BizActivity {
140///   pub id: Option<String>,
141///   pub name: Option<String>,
142///   pub version: Option<i32>,
143///   pub delete_flag: Option<i32>,
144/// }
145#[proc_macro_attribute]
146pub fn mybatis_plus(args: TokenStream, input: TokenStream) -> TokenStream {
147    let stream = impl_mybatis_plus(args, input);
148    #[cfg(feature = "debug_mode")]
149    {
150        println!("............gen impl CRUDTable:\n {}", stream);
151        println!("............gen impl CRUDTable end............");
152    }
153
154    return stream;
155}
156
157#[proc_macro_attribute]
158pub fn expr(args: TokenStream, func: TokenStream) -> TokenStream {
159    //let args = parse_macro_input!(args as AttributeArgs);
160    let target_fn: ItemFn = syn::parse(func).unwrap();
161    let stream = func::impl_fn(
162        "",
163        &target_fn.sig.ident.to_string(),
164        &args.to_string(),
165        true,
166        true,
167        &[],
168    )
169    .into();
170    #[cfg(feature = "debug_mode")]
171    {
172        println!("............gen macro rexpr:\n {}", stream);
173        println!("............gen macro rexpr end............");
174    }
175    stream
176}
177
178#[proc_macro_attribute]
179pub fn html(args: TokenStream, func: TokenStream) -> TokenStream {
180    let args = parse_macro_input!(args as AttributeArgs);
181    let target_fn = syn::parse(func).unwrap();
182    let stream = parser::impl_fn_html(&target_fn, &args);
183    #[cfg(feature = "debug_mode")]
184    {
185        println!("............gen macro xml:\n {}", stream);
186        println!("............gen macro xml end............");
187    }
188    stream
189}
190
191/// support py_sql fn convert
192#[proc_macro_attribute]
193pub fn py(args: TokenStream, func: TokenStream) -> TokenStream {
194    let args = parse_macro_input!(args as AttributeArgs);
195    let target_fn = syn::parse(func).unwrap();
196    let stream = parser::impl_fn_py(&target_fn, &args);
197    #[cfg(feature = "debug_mode")]
198    {
199        println!("............gen pysql_fn:\n {}", stream);
200        println!("............gen pysql_fn end............");
201    }
202    stream
203}