bevy_reflect_derive/
generics.rs1use crate::derive_data::ReflectMeta;
2use proc_macro2::TokenStream;
3use quote::quote;
4use syn::punctuated::Punctuated;
5use syn::{GenericParam, Token};
6
7pub(crate) fn generate_generics(meta: &ReflectMeta) -> Option<TokenStream> {
11 if !meta.attrs().type_path_attrs().should_auto_derive() {
12 return None;
14 }
15
16 let bevy_reflect_path = meta.bevy_reflect_path();
17
18 let generics = meta
19 .type_path()
20 .generics()
21 .params
22 .iter()
23 .filter_map(|param| match param {
24 GenericParam::Type(ty_param) => {
25 let ident = &ty_param.ident;
26 let name = ident.to_string();
27 let with_default = ty_param
28 .default
29 .as_ref()
30 .map(|default_ty| quote!(.with_default::<#default_ty>()));
31
32 Some(quote! {
33 #bevy_reflect_path::GenericInfo::Type(
34 #bevy_reflect_path::TypeParamInfo::new::<#ident>(
35 #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(#name),
36 )
37 #with_default
38 )
39 })
40 }
41 GenericParam::Const(const_param) => {
42 let ty = &const_param.ty;
43 let name = const_param.ident.to_string();
44 let with_default = const_param.default.as_ref().map(|default| {
45 quote!(.with_default(#default as #ty))
47 });
48
49 Some(quote! {
50 #[allow(
51 clippy::unnecessary_cast,
52 reason = "reflection requires an explicit type hint for const generics"
53 )]
54 #bevy_reflect_path::GenericInfo::Const(
55 #bevy_reflect_path::ConstParamInfo::new::<#ty>(
56 #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(#name),
57 )
58 #with_default
59 )
60 })
61 }
62 GenericParam::Lifetime(_) => None,
63 })
64 .collect::<Punctuated<_, Token![,]>>();
65
66 if generics.is_empty() {
67 return None;
69 }
70
71 Some(quote!(#bevy_reflect_path::Generics::from_iter([ #generics ])))
72}