From f10dd3a9de75cf8b33e2462d2987d8fd5c82fcb4 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sat, 21 Oct 2023 16:19:55 -0700 Subject: [PATCH] Fix skip_serializing not using custom default functions --- .../bevy_reflect_derive/src/serialization.rs | 14 ++-- crates/bevy_reflect/src/serde/mod.rs | 68 +++++++++++++++---- 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs b/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs index 4421d5d66e5ef..0242947b5c91f 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs @@ -1,5 +1,5 @@ use crate::derive_data::StructField; -use crate::field_attributes::ReflectIgnoreBehavior; +use crate::field_attributes::{DefaultBehavior, ReflectIgnoreBehavior}; use bevy_macro_utils::fq_std::{FQBox, FQDefault}; use quote::quote; use std::collections::HashMap; @@ -76,10 +76,16 @@ pub(crate) struct SkippedFieldDef { impl SkippedFieldDef { pub fn new(field: &StructField<'_>) -> Result { let ty = &field.data.ty; - Ok(Self { - default_fn: quote! { + + let default_fn = match &field.attrs.default { + DefaultBehavior::Func(func) => quote! { + || { #FQBox::new(#func()) } + }, + _ => quote! { || { #FQBox::new(<#ty as #FQDefault>::default()) } }, - }) + }; + + Ok(Self { default_fn }) } } diff --git a/crates/bevy_reflect/src/serde/mod.rs b/crates/bevy_reflect/src/serde/mod.rs index 2d6ee20798620..c444279fa928a 100644 --- a/crates/bevy_reflect/src/serde/mod.rs +++ b/crates/bevy_reflect/src/serde/mod.rs @@ -26,7 +26,14 @@ mod tests { b: i32, #[reflect(skip_serializing)] c: i32, + #[reflect(skip_serializing)] + #[reflect(default = "custom_default")] d: i32, + e: i32, + } + + fn custom_default() -> i32 { + -1 } let mut registry = TypeRegistry::default(); @@ -37,25 +44,42 @@ mod tests { b: 4, c: 5, d: 6, + e: 7, }; let serializer = ReflectSerializer::new(&test_struct, ®istry); let serialized = ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap(); - let mut expected = DynamicStruct::default(); - expected.insert("a", 3); - expected.insert("d", 6); - expected.insert("c", 0); - let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap(); let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let deserialized = value.take::().unwrap(); + let mut expected = DynamicStruct::default(); + expected.insert("a", 3); + // Ignored: expected.insert("b", 0); + expected.insert("c", 0); + expected.insert("d", -1); + expected.insert("e", 7); + assert!( expected.reflect_partial_eq(&deserialized).unwrap(), - "Expected {expected:?} found {deserialized:?}" + "Deserialization failed: expected {expected:?} found {deserialized:?}" + ); + + let expected = TestStruct { + a: 3, + b: 0, + c: 0, + d: -1, + e: 7, + }; + let received = ::from_reflect(&deserialized).unwrap(); + + assert_eq!( + expected, received, + "FromReflect failed: expected {expected:?} found {received:?}" ); } @@ -67,31 +91,49 @@ mod tests { i32, #[reflect(ignore)] i32, #[reflect(skip_serializing)] i32, + #[reflect(skip_serializing)] + #[reflect(default = "custom_default")] + i32, i32, ); + fn custom_default() -> i32 { + -1 + } + let mut registry = TypeRegistry::default(); registry.register::(); - let test_struct = TestStruct(3, 4, 5, 6); + let test_struct = TestStruct(3, 4, 5, 6, 7); let serializer = ReflectSerializer::new(&test_struct, ®istry); let serialized = ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap(); - let mut expected = DynamicTupleStruct::default(); - expected.insert(3); - expected.insert(6); - let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap(); let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let deserialized = value.take::().unwrap(); - let expected = TestStruct(3, 0, 0, 6); + let mut expected = DynamicTupleStruct::default(); + expected.insert(3); + // Ignored: expected.insert(0); + expected.insert(0); + expected.insert(-1); + expected.insert(7); + + assert!( + expected.reflect_partial_eq(&deserialized).unwrap(), + "Deserialization failed: expected {expected:?} found {deserialized:?}" + ); + + let expected = TestStruct(3, 0, 0, -1, 7); let received = ::from_reflect(&deserialized).unwrap(); - assert_eq!(expected, received); + assert_eq!( + expected, received, + "FromReflect failed: expected {expected:?} found {received:?}" + ); } #[test]