This repository has been archived on 2024-05-26. You can view files and clone it, but cannot push or open issues or pull requests.
core/lua_macros/src/lib.rs

70 lines
2.6 KiB
Rust
Raw Normal View History

mod mark_as_ci_command;
mod struct_to_ci_enum;
use mark_as_ci_command::generate_final_function;
use proc_macro::TokenStream;
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{format_ident, quote};
use struct_to_ci_enum::{generate_command_enum, generate_generate_ci_function, generate_help_function};
use syn::{self, parse_quote, parse_str, DeriveInput, FieldMutability, ItemFn, Token, Visibility};
#[proc_macro_attribute]
pub fn turn_struct_to_ci_command_enum(_attrs: TokenStream, input: TokenStream) -> TokenStream {
// Construct a representation of Rust code as a syntax tree
// that we can manipulate
let mut input: DeriveInput = syn::parse(input).expect("This should always be valid rust code, as it's extracted from direct code");
let mut named_fields = match &input.data {
syn::Data::Struct(input) => match &input.fields {
syn::Fields::Named(named_fields) => named_fields,
_ => unimplemented!("The macro only works for named fields (e.g.: `Name: Type`)"),
},
_ => unimplemented!("The macro only works for structs"),
}
.to_owned();
let attr_parsed = parse_quote! {
/// This is a help function
};
named_fields.named.push(syn::Field {
attrs: vec![attr_parsed],
// attrs: attr_parser
// .parse("#[doc = r\"This is a help function\"]".to_token_stream().into())
// .expect("See reason for other one"),
vis: Visibility::Inherited,
mutability: FieldMutability::None,
ident: Some(format_ident!("help")),
colon_token: Some(Token![:](Span::call_site())),
ty: parse_str("fn(Option<String>) -> String").expect("This is static and valid rust code"),
});
match &mut input.data {
syn::Data::Struct(input) => input.fields = syn::Fields::Named(named_fields.clone()),
_ => unreachable!("This was a DataStruct before"),
};
// Build the trait implementation
let generate_ci_function: TokenStream2 = generate_generate_ci_function(&input);
let command_enum = generate_command_enum(&named_fields);
let help_function = generate_help_function(&named_fields);
quote! {
#command_enum
#generate_ci_function
//#help_function
}
.into()
}
#[proc_macro_attribute]
pub fn ci_command(_attrs: TokenStream, input: TokenStream) -> TokenStream {
let mut input: ItemFn = syn::parse(input).expect("This should always be valid rust code, as it's extracted from direct code");
let output_function = generate_final_function(&mut input);
output_function.into()
}