subject_derive/
lib.rs

1mod attrs;
2mod fields;
3mod into_subject;
4mod subject;
5
6use proc_macro::TokenStream;
7use quote::quote;
8use syn::{parse_macro_input, DeriveInput};
9
10#[proc_macro_derive(Subject, attributes(subject))]
11pub fn subject_derive(input: TokenStream) -> TokenStream {
12    let input = parse_macro_input!(input as DeriveInput);
13    let name = &input.ident;
14
15    let fields = fields::from_input(&input).unwrap();
16    let field_infos = fields::names_from_fields(fields);
17    let field_names: Vec<_> = field_infos.iter().map(|f| f.ident).collect();
18    let field_types = fields::types_from_fields(fields);
19
20    let id_fn = into_subject::id_fn();
21    let query_all_fn = into_subject::query_all_fn();
22    let parse_fn = into_subject::parse_fn(&input, &field_names);
23    let to_sql_where_fn = into_subject::to_sql_where_fn(&field_infos);
24    let to_sql_select_fn = into_subject::to_sql_select_fn(&field_infos);
25    let to_payload_fn = into_subject::to_payload_fn(&input);
26    let schema_fn = into_subject::schema_fn(
27        &input,
28        &field_infos,
29        &field_names,
30        &field_types,
31    );
32
33    let subject_expanded = subject::expanded(
34        name,
35        &field_names,
36        &field_types,
37        &field_infos,
38        &input.attrs,
39    );
40
41    quote! {
42        #subject_expanded
43
44        impl fuel_streams_subject::subject::SubjectBuildable for #name {
45            fn new() -> Self {
46                Self {
47                    #(#field_names: None,)*
48                }
49            }
50        }
51
52        impl IntoSubject for #name {
53            #id_fn
54            #parse_fn
55            #query_all_fn
56            #to_sql_where_fn
57            #to_sql_select_fn
58            #schema_fn
59            #to_payload_fn
60        }
61    }
62    .into()
63}