60 lines
2.3 KiB
Rust
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()
|
||
|
}
|