1use proc_macro_error::{abort, emit_error, proc_macro_error};
2use syn::parse_macro_input;
3
4mod model;
5use model::Model;
6mod ir;
7use ir::Ir;
8mod codegen;
9use codegen::codegen;
10mod errors;
11use errors::{GetSpan, Help};
12
13#[proc_macro_attribute]
16#[proc_macro_error]
17pub fn dbstruct(
18 attr: proc_macro::TokenStream,
19 item: proc_macro::TokenStream,
20) -> proc_macro::TokenStream {
21 let input = parse_macro_input!(item as syn::ItemStruct);
22
23 let model = match Model::try_from(input, attr.into()) {
24 Ok(model) => model,
25 Err(err) => emit_and_abort(err),
26 };
27
28 let ir = Ir::from(model);
29 let code = codegen(ir);
30 code.into()
31}
32
33fn emit_and_abort(err: model::Error) -> ! {
34 match err {
35 model::Error::DbKey(e) => {
36 abort!(e.span(), "{}", e)
37 }
38 model::Error::Field(mut errs) => {
39 let last = errs.pop().expect("minimum err vec len is one");
40 for e in errs {
41 emit_error!(e.span(), e.to_string(); help =? e.help(););
42 }
43 abort!(last.span(),last.to_string(); help =? last.help(););
44 }
45 model::Error::Attribute(e) => {
46 abort!(e.span(), e.to_string(); help =? e.help(););
47 }
48 model::Error::Backend(e) => {
49 abort!(e.span(), e.to_string(); help =? e.help(););
50 }
51 }
52}
53