tiny_orm/
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
#![allow(dead_code)]
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

mod attr;
mod database;
mod quotes;

#[proc_macro_derive(TinyORM, 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.struct_name.clone();

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

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

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

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

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

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