tiny_orm_macros/
lib.rs

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
72
73
74
use proc_macro::TokenStream;
use quote::quote;
use quotes::get_table_name;
use syn::{parse_macro_input, DeriveInput};
use types::Operation;

mod attr;
mod database;
mod quotes;
mod types;

#[proc_macro_derive(Table, attributes(tiny_orm))]
pub fn derive_tiny_orm(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let attr = attr::Attr::parse(input);

    let expanded = generate_impl(&attr);

    #[cfg(test)]
    println!("Generated code:\n{}", expanded);

    TokenStream::from(expanded)
}

fn generate_impl(attr: &attr::Attr) -> proc_macro2::TokenStream {
    let struct_name = attr.parsed_struct.name.clone();

    let table_name_fn = if attr.parsed_struct.struct_type == types::StructType::Generic {
        get_table_name(attr)
    } else {
        quote! {}
    };

    let get_impl = if attr.operations.contains(&Operation::Get) {
        quotes::get_by_id_fn(attr)
    } else {
        quote! {}
    };

    let list_impl = if attr.operations.contains(&Operation::List) {
        quotes::list_all_fn(attr)
    } else {
        quote! {}
    };

    let create_impl = if attr.operations.contains(&Operation::Create) {
        quotes::create_fn(attr)
    } else {
        quote! {}
    };

    let update_impl = if attr.operations.contains(&Operation::Update) {
        quotes::update_fn(attr)
    } else {
        quote! {}
    };

    let delete_impl = if attr.operations.contains(&Operation::Delete) {
        quotes::delete_fn(attr)
    } else {
        quote! {}
    };

    quote! {
        impl #struct_name {
            #table_name_fn
            #get_impl
            #list_impl
            #create_impl
            #update_impl
            #delete_impl
        }
    }
}