
# Objective - Fixes #5432 - Fixes #6680 ## Solution - move code responsible for generating the `impl TypeUuid` from `type_uuid_derive` into a new function, `gen_impl_type_uuid`. - this allows the new proc macro, `impl_type_uuid`, to call the code for generation. - added struct `TypeUuidDef` and implemented `syn::Parse` to allow parsing of the input for the new macro. - finally, used the new macro `impl_type_uuid` to implement `TypeUuid` for the standard library (in `crates/bevy_reflect/src/type_uuid_impl.rs`). - fixes #6680 by doing a wrapping add of the param's index to its `TYPE_UUID` Co-authored-by: dis-da-moe <84386186+dis-da-moe@users.noreply.github.com>
72 lines
1.8 KiB
Rust
72 lines
1.8 KiB
Rust
use proc_macro::TokenStream;
|
|
use quote::{format_ident, quote};
|
|
use syn::{
|
|
parse::{Parse, ParseStream},
|
|
parse_macro_input,
|
|
token::Comma,
|
|
Ident, LitInt, Result,
|
|
};
|
|
struct AllTuples {
|
|
macro_ident: Ident,
|
|
start: usize,
|
|
end: usize,
|
|
idents: Vec<Ident>,
|
|
}
|
|
|
|
impl Parse for AllTuples {
|
|
fn parse(input: ParseStream) -> Result<Self> {
|
|
let macro_ident = input.parse::<Ident>()?;
|
|
input.parse::<Comma>()?;
|
|
let start = input.parse::<LitInt>()?.base10_parse()?;
|
|
input.parse::<Comma>()?;
|
|
let end = input.parse::<LitInt>()?.base10_parse()?;
|
|
input.parse::<Comma>()?;
|
|
let mut idents = vec![input.parse::<Ident>()?];
|
|
while input.parse::<Comma>().is_ok() {
|
|
idents.push(input.parse::<Ident>()?);
|
|
}
|
|
|
|
Ok(AllTuples {
|
|
macro_ident,
|
|
start,
|
|
end,
|
|
idents,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[proc_macro]
|
|
pub fn all_tuples(input: TokenStream) -> TokenStream {
|
|
let input = parse_macro_input!(input as AllTuples);
|
|
let len = input.end - input.start;
|
|
let mut ident_tuples = Vec::with_capacity(len);
|
|
for i in input.start..=input.end {
|
|
let idents = input
|
|
.idents
|
|
.iter()
|
|
.map(|ident| format_ident!("{}{}", ident, i));
|
|
if input.idents.len() < 2 {
|
|
ident_tuples.push(quote! {
|
|
#(#idents)*
|
|
});
|
|
} else {
|
|
ident_tuples.push(quote! {
|
|
(#(#idents),*)
|
|
});
|
|
}
|
|
}
|
|
|
|
let macro_ident = &input.macro_ident;
|
|
let invocations = (input.start..=input.end).map(|i| {
|
|
let ident_tuples = &ident_tuples[..i];
|
|
quote! {
|
|
#macro_ident!(#(#ident_tuples),*);
|
|
}
|
|
});
|
|
TokenStream::from(quote! {
|
|
#(
|
|
#invocations
|
|
)*
|
|
})
|
|
}
|