1use proc_macro::TokenStream;
2use quote::quote;
3use quotes::get_table_name;
4use syn::{parse_macro_input, DeriveInput};
5use types::Operation;
6
7mod attr;
8mod database;
9mod quotes;
10mod types;
11
12#[proc_macro_derive(Table, attributes(tiny_orm))]
13pub fn derive_tiny_orm(input: TokenStream) -> TokenStream {
14 let input = parse_macro_input!(input as DeriveInput);
15 let attr = attr::Attr::parse(input);
16
17 let expanded = generate_impl(&attr);
18
19 #[cfg(test)]
20 println!("Generated code:\n{}", expanded);
21
22 TokenStream::from(expanded)
23}
24
25fn generate_impl(attr: &attr::Attr) -> proc_macro2::TokenStream {
26 let struct_name = attr.parsed_struct.name.clone();
27
28 let table_name_fn = if attr.parsed_struct.struct_type == types::StructType::Generic {
29 get_table_name(attr)
30 } else {
31 quote! {}
32 };
33
34 let get_impl = if attr.operations.contains(&Operation::Get) {
35 quotes::get_by_id_fn(attr)
36 } else {
37 quote! {}
38 };
39
40 let list_impl = if attr.operations.contains(&Operation::List) {
41 quotes::list_all_fn(attr)
42 } else {
43 quote! {}
44 };
45
46 let create_impl = if attr.operations.contains(&Operation::Create) {
47 quotes::create_fn(attr)
48 } else {
49 quote! {}
50 };
51
52 let update_impl = if attr.operations.contains(&Operation::Update) {
53 quotes::update_fn(attr)
54 } else {
55 quote! {}
56 };
57
58 let delete_impl = if attr.operations.contains(&Operation::Delete) {
59 quotes::delete_fn(attr)
60 } else {
61 quote! {}
62 };
63
64 quote! {
65 impl #struct_name {
66 #table_name_fn
67 #get_impl
68 #list_impl
69 #create_impl
70 #update_impl
71 #delete_impl
72 }
73 }
74}