Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/macros/src/variant_defaults.rs
30636 views
1
use bevy_macro_utils::fq_std::FQDefault;
2
use proc_macro::TokenStream;
3
use quote::{format_ident, quote, ToTokens};
4
use syn::{parse_macro_input, Data, DeriveInput};
5
6
pub(crate) fn derive_variant_defaults(input: TokenStream) -> TokenStream {
7
let ast = parse_macro_input!(input as DeriveInput);
8
let type_ident = &ast.ident;
9
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
10
let Data::Enum(data_enum) = &ast.data else {
11
panic!("Can only derive VariantDefaults for enums");
12
};
13
14
let mut variant_defaults = Vec::new();
15
for variant in &data_enum.variants {
16
let variant_ident = &variant.ident;
17
let variant_name_lower = variant_ident.to_string().to_lowercase();
18
let variant_default_name = format_ident!("default_{}", variant_name_lower);
19
match &variant.fields {
20
syn::Fields::Named(fields_named) => {
21
let fqdefault = FQDefault.into_token_stream();
22
let fields = fields_named.named.iter().map(|f| &f.ident);
23
variant_defaults.push(quote! {
24
#[allow(missing_docs)]
25
pub fn #variant_default_name() -> Self {
26
Self::#variant_ident {
27
#(#fields: #fqdefault::default(),)*
28
}
29
}
30
});
31
}
32
syn::Fields::Unnamed(fields_unnamed) => {
33
let fields = fields_unnamed
34
.unnamed
35
.iter()
36
.map(|_| quote! {#FQDefault::default()});
37
variant_defaults.push(quote! {
38
#[allow(missing_docs)]
39
pub fn #variant_default_name() -> Self {
40
Self::#variant_ident(
41
#(#fields,)*
42
)
43
}
44
});
45
}
46
syn::Fields::Unit => {
47
variant_defaults.push(quote! {
48
#[allow(missing_docs)]
49
pub fn #variant_default_name() -> Self {
50
Self::#variant_ident
51
}
52
});
53
}
54
}
55
}
56
57
TokenStream::from(quote! {
58
impl #impl_generics #type_ident #type_generics #where_clause {
59
#(#variant_defaults)*
60
}
61
})
62
}
63
64