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