Path: blob/main/crates/bevy_reflect/derive/src/impls/structs.rs
9390 views
use crate::{1impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},2struct_utility::FieldAccessors,3ReflectStruct,4};5use bevy_macro_utils::fq_std::{FQDefault, FQOption, FQResult};6use quote::{quote, ToTokens};78/// Implements `Struct`, `GetTypeRegistration`, and `Reflect` for the given derive data.9pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenStream {10let fqoption = FQOption.into_token_stream();1112let bevy_reflect_path = reflect_struct.meta().bevy_reflect_path();13let struct_path = reflect_struct.meta().type_path();1415let field_names = reflect_struct16.active_fields()17.map(|field| {18field19.data20.ident21.as_ref()22.map(ToString::to_string)23.unwrap_or_else(|| field.declaration_index.to_string())24})25.collect::<Vec<String>>();2627let FieldAccessors {28fields_ref,29fields_mut,30field_indices,31field_count,32..33} = FieldAccessors::new(reflect_struct);3435let where_clause_options = reflect_struct.where_clause_options();36let typed_impl = impl_typed(&where_clause_options, reflect_struct.to_info_tokens(false));3738let type_path_impl = impl_type_path(reflect_struct.meta());39let full_reflect_impl = impl_full_reflect(&where_clause_options);40let common_methods = common_partial_reflect_methods(41reflect_struct.meta(),42|| Some(quote!(#bevy_reflect_path::structs::struct_partial_eq)),43|| None,44|| Some(quote!(#bevy_reflect_path::structs::struct_partial_cmp)),45);46let clone_fn = reflect_struct.get_clone_impl();4748#[cfg(not(feature = "functions"))]49let function_impls = None::<proc_macro2::TokenStream>;50#[cfg(feature = "functions")]51let function_impls = crate::impls::impl_function_traits(&where_clause_options);5253let get_type_registration_impl = reflect_struct.get_type_registration(&where_clause_options);5455let (impl_generics, ty_generics, where_clause) = reflect_struct56.meta()57.type_path()58.generics()59.split_for_impl();6061#[cfg(not(feature = "auto_register"))]62let auto_register = None::<proc_macro2::TokenStream>;63#[cfg(feature = "auto_register")]64let auto_register = crate::impls::reflect_auto_registration(reflect_struct.meta());6566let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);6768quote! {69#get_type_registration_impl7071#typed_impl7273#type_path_impl7475#full_reflect_impl7677#function_impls7879#auto_register8081impl #impl_generics #bevy_reflect_path::structs::Struct for #struct_path #ty_generics #where_reflect_clause {82fn field(&self, name: &str) -> #FQOption<&dyn #bevy_reflect_path::PartialReflect> {83match name {84#(#field_names => #fqoption::Some(#fields_ref),)*85_ => #FQOption::None,86}87}8889fn field_mut(&mut self, name: &str) -> #FQOption<&mut dyn #bevy_reflect_path::PartialReflect> {90match name {91#(#field_names => #fqoption::Some(#fields_mut),)*92_ => #FQOption::None,93}94}9596fn field_at(&self, index: usize) -> #FQOption<&dyn #bevy_reflect_path::PartialReflect> {97match index {98#(#field_indices => #fqoption::Some(#fields_ref),)*99_ => #FQOption::None,100}101}102103fn field_at_mut(&mut self, index: usize) -> #FQOption<&mut dyn #bevy_reflect_path::PartialReflect> {104match index {105#(#field_indices => #fqoption::Some(#fields_mut),)*106_ => #FQOption::None,107}108}109110fn name_at(&self, index: usize) -> #FQOption<&str> {111match index {112#(#field_indices => #fqoption::Some(#field_names),)*113_ => #FQOption::None,114}115}116117fn index_of_name(&self, name: &str) -> #FQOption<usize> {118match name {119#(#field_names => #fqoption::Some(#field_indices),)*120_ => #FQOption::None,121}122}123124fn field_len(&self) -> usize {125#field_count126}127128fn iter_fields(&self) -> #bevy_reflect_path::structs::FieldIter {129#bevy_reflect_path::structs::FieldIter::new(self)130}131132fn to_dynamic_struct(&self) -> #bevy_reflect_path::structs::DynamicStruct {133let mut dynamic: #bevy_reflect_path::structs::DynamicStruct = #FQDefault::default();134dynamic.set_represented_type(#bevy_reflect_path::PartialReflect::get_represented_type_info(self));135#(dynamic.insert_boxed(#field_names, #bevy_reflect_path::PartialReflect::to_dynamic(#fields_ref));)*136dynamic137}138}139140impl #impl_generics #bevy_reflect_path::PartialReflect for #struct_path #ty_generics #where_reflect_clause {141#[inline]142fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {143#FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())144}145146#[inline]147fn try_apply(148&mut self,149value: &dyn #bevy_reflect_path::PartialReflect150) -> #FQResult<(), #bevy_reflect_path::ApplyError> {151if let #bevy_reflect_path::ReflectRef::Struct(struct_value)152= #bevy_reflect_path::PartialReflect::reflect_ref(value) {153for (name, value) in #bevy_reflect_path::structs::Struct::iter_fields(struct_value) {154if let #FQOption::Some(v) = #bevy_reflect_path::structs::Struct::field_mut(self, name) {155#bevy_reflect_path::PartialReflect::try_apply(v, value)?;156}157}158} else {159return #FQResult::Err(160#bevy_reflect_path::ApplyError::MismatchedKinds {161from_kind: #bevy_reflect_path::PartialReflect::reflect_kind(value),162to_kind: #bevy_reflect_path::ReflectKind::Struct163}164);165}166#FQResult::Ok(())167}168#[inline]169fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {170#bevy_reflect_path::ReflectKind::Struct171}172#[inline]173fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {174#bevy_reflect_path::ReflectRef::Struct(self)175}176#[inline]177fn reflect_mut(&mut self) -> #bevy_reflect_path::ReflectMut {178#bevy_reflect_path::ReflectMut::Struct(self)179}180#[inline]181fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::ReflectOwned {182#bevy_reflect_path::ReflectOwned::Struct(self)183}184185#common_methods186187#clone_fn188}189}190}191192193