1use {
2 attr::Attributes,
3 proc_macro::TokenStream,
4 proc_macro2::TokenStream as TokenStream2,
5 quote::quote,
6 syn::{Data, DeriveInput, parse_macro_input},
7};
8
9mod attr;
10pub(crate) mod builder;
11mod r#enum;
12mod shared;
13pub(crate) mod r#struct;
14
15macro_rules! dbg {
16 ($val:expr $(,)?) => {
17 match $val {
20 tmp => {
21 #[cfg(feature = "debug")]
22 eprintln!(
23 "[{}:{}:{}] {} = {}",
24 std::file!(),
25 std::line!(),
26 std::column!(),
27 std::stringify!($val),
28 &tmp
29 );
30 tmp
31 },
32 }
33 };
34}
35
36#[proc_macro_attribute]
37pub fn mlua_gen(args: TokenStream, input: TokenStream) -> TokenStream {
38 let input = parse_macro_input!(input as DeriveInput);
39 let name = &input.ident;
40 let generics = &input.generics;
41
42 let mut attributes = Attributes::default();
43 let attr_parser = syn::meta::parser(|meta| attributes.parse(&meta));
44 parse_macro_input!(args with attr_parser);
45
46 let code = match input.data {
47 Data::Struct(ref ds) => {
48 match (|| -> syn::Result<TokenStream2> {
49 let field_get = attributes.get.fields_from_visibility(&ds.fields)?;
50 let field_set = attributes.set.fields_from_visibility(&ds.fields)?;
51
52 let builder = r#struct::builder(
53 name,
54 ds,
55 attributes
56 .r#impl
57 .iter()
58 .filter(|fun| !fun.is_self)
59 .collect(),
60 generics,
61 );
62
63 let user_data = r#struct::user_data(
64 name,
65 generics,
66 &ds.fields,
67 field_get,
68 field_set,
69 attributes.custom_fields,
70 attributes.r#impl,
71 attributes.custom_impls,
72 );
73
74 Ok(quote!(#builder #user_data))
75 })() {
76 Ok(e) => e,
78 Err(synerr) => return synerr.into_compile_error().into(),
79 }
80 },
81 Data::Enum(ref de) => {
82 let builder = r#enum::builder(
83 name,
84 de,
85 attributes
86 .r#impl
87 .iter()
88 .filter(|fun| !fun.is_self)
89 .collect(),
90 generics,
91 );
92 let user_data = r#enum::user_data(
93 name,
94 generics,
95 de.variants.iter(),
96 attributes.custom_fields,
97 attributes.custom_impls,
98 );
99 dbg!(quote!(#builder #user_data))
100 },
101 Data::Union(_) => panic!("Must annotate struct or enum"),
102 };
103
104 quote! {
105 #input
106
107 #code
108 }
109 .into()
110}