forked from trinitrix/core
1
0
Fork 0
core/lua_macros/src/lib.rs

60 lines
2.3 KiB
Rust

use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote};
use syn;
#[proc_macro_attribute]
pub fn generate_ci_functions(_: TokenStream, input: TokenStream) -> TokenStream {
// Construct a representation of Rust code as a syntax tree
// that we can manipulate
let input = syn::parse(input)
.expect("This should always be valid rust code, as it's extracted from direct code");
// Build the trait implementation
generate_generate_ci_functions(&input)
}
fn generate_generate_ci_functions(input: &syn::DeriveInput) -> TokenStream {
let input_tokens: TokenStream2 = match &input.data {
syn::Data::Struct(input) => match &input.fields {
syn::Fields::Named(named_fields) => named_fields
.named
.iter()
.map(|field| -> TokenStream2 {
let field_ident = field.ident.as_ref().expect(
"These are only the named field, thus they all should have a name.",
);
let function_name_ident = format_ident!("fun_{}", field_ident);
let function_name = format!("{}", field_ident);
quote! {
let #function_name_ident = context.create_function(#field_ident).expect(
&format!(
"The function: `{}` should be defined",
#function_name
)
);
globals.set(#function_name, #function_name_ident).expect(
&format!(
"Setting a static global value ({}, fun_{}) should work",
#function_name,
#function_name
)
);
}
.into()
})
.collect(),
_ => unimplemented!("Only implemented for named fileds"),
},
_ => unimplemented!("Only for implemented for structs"),
};
let gen = quote! {
pub fn generate_ci_functions(context: &mut Context) {
let globals = context.globals();
#input_tokens
}
};
gen.into()
}