proc_macro_roids
Traits and functions to make writing proc macros more ergonomic.
Suppose you want to write a proc macro, that takes in this struct (example repo):
use std::marker::PhantomData;
use super_derive::Super;
#[derive(Super)]
pub struct Man<T> {
#[super_derive(skip)]
name: String,
power_level: u64,
marker: PhantomData<T>,
}
And generates this:
pub enum SuperMan {
U64(u64),
}
Traversing the syntax tree is verbose, and writing error messages for each incorrect traversal is tedious.
With proc_macro_roids
, the procedural macro code to implement the above is concise and expressive:
#[proc_macro_derive(Super, attributes(super_derive))]
pub fn system_desc_derive(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let enum_name = ast.ident.prepend("Super");
let fields = ast.fields();
let relevant_fields = fields
.iter()
.filter(|field| !field.is_phantom_data())
.filter(|field| !field.contains_tag(&parse_quote!(super_derive), &parse_quote!(skip)));
let variants = relevant_fields
.map(|field| {
let type_name = field.type_name();
let variant_name = type_name.to_string().to_uppercase();
let variant_name = Ident::new(&variant_name, Span::call_site());
quote! {
#variant_name(#type_name)
}
})
.collect::<Vec<_>>();
let token_stream2 = quote! {
pub enum #enum_name {
#(#variants,)*
}
};
token_stream2.into()
}
What's new:
0.5.0 (2019-08-19)
-
syn
,quote
, andproc_macro2
are upgraded to1.0
. -
Breaking:
nested_meta_to_ident
is renamed tonested_meta_to_path
.
0.4.0 (2019-08-17)
-
Breaking:
DeriveInputDeriveExt
is renamed toDeriveInputExt
. -
FieldExt::tag_parameter
extracts theMeta
param from#[namespace(tag(param))]
. -
FieldExt::tag_parameters
extracts theMeta
params from#[namespace(tag(param1, param2))]
. -
DeriveInputExt::tag_parameter
extracts theMeta
param from#[namespace(tag(param))]
. -
DeriveInputExt::tag_parameters
extracts theMeta
params from#[namespace(tag(param1, param2))]
.
0.3.0
-
FieldExt
provides methods to work withField
s:contains_tag
is_phantom_data
type_name