1#![cfg_attr(
2 any(docsrs, docsrs_dep),
3 expect(
4 internal_features,
5 reason = "rustdoc_internals is needed for fake_variadic"
6 )
7)]
8#![cfg_attr(any(docsrs, docsrs_dep), feature(doc_cfg, rustdoc_internals))]
9#![doc(
10 html_logo_url = "https://bevy.org/assets/icon.png",
11 html_favicon_url = "https://bevy.org/assets/icon.png"
12)]
13
14#![no_std]
571
572#[cfg(feature = "std")]
573extern crate std;
574
575extern crate alloc;
576
577extern crate self as bevy_reflect;
579
580mod array;
581mod error;
582mod fields;
583mod from_reflect;
584#[cfg(feature = "functions")]
585pub mod func;
586mod is;
587mod kind;
588mod list;
589mod map;
590mod path;
591mod reflect;
592mod reflectable;
593mod remote;
594mod set;
595mod struct_trait;
596mod tuple;
597mod tuple_struct;
598mod type_info;
599mod type_path;
600mod type_registry;
601
602mod impls {
603 mod alloc;
604 mod bevy_platform;
605 mod core;
606 mod foldhash;
607 #[cfg(feature = "hashbrown")]
608 mod hashbrown;
609 mod macros;
610 #[cfg(feature = "std")]
611 mod std;
612
613 #[cfg(feature = "glam")]
614 mod glam;
615 #[cfg(feature = "petgraph")]
616 mod petgraph;
617 #[cfg(feature = "smallvec")]
618 mod smallvec;
619 #[cfg(feature = "smol_str")]
620 mod smol_str;
621 #[cfg(feature = "uuid")]
622 mod uuid;
623 #[cfg(feature = "wgpu-types")]
624 mod wgpu_types;
625}
626
627pub mod attributes;
628mod enums;
629mod generics;
630pub mod serde;
631pub mod std_traits;
632#[cfg(feature = "debug_stack")]
633mod type_info_stack;
634pub mod utility;
635
636pub mod prelude {
640 pub use crate::std_traits::*;
641
642 #[doc(hidden)]
643 pub use crate::{
644 reflect_trait, FromReflect, GetField, GetPath, GetTupleStructField, PartialReflect,
645 Reflect, ReflectDeserialize, ReflectFromReflect, ReflectPath, ReflectSerialize, Struct,
646 TupleStruct, TypePath,
647 };
648
649 #[cfg(feature = "functions")]
650 pub use crate::func::{Function, IntoFunction, IntoFunctionMut};
651}
652
653pub use array::*;
654pub use enums::*;
655pub use error::*;
656pub use fields::*;
657pub use from_reflect::*;
658pub use generics::*;
659pub use is::*;
660pub use kind::*;
661pub use list::*;
662pub use map::*;
663pub use path::*;
664pub use reflect::*;
665pub use reflectable::*;
666pub use remote::*;
667pub use set::*;
668pub use struct_trait::*;
669pub use tuple::*;
670pub use tuple_struct::*;
671pub use type_info::*;
672pub use type_path::*;
673pub use type_registry::*;
674
675pub use bevy_reflect_derive::*;
676pub use erased_serde;
677
678#[doc(hidden)]
682pub mod __macro_exports {
683 use crate::{
684 DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, DynamicTuple,
685 DynamicTupleStruct, GetTypeRegistration, TypeRegistry,
686 };
687
688 pub mod alloc_utils {
693 pub use ::alloc::{
694 borrow::{Cow, ToOwned},
695 boxed::Box,
696 string::ToString,
697 };
698 }
699
700 #[diagnostic::on_unimplemented(
709 message = "`{Self}` does not implement `GetTypeRegistration` so cannot be registered for reflection",
710 note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
711 )]
712 pub trait RegisterForReflection {
713 #[expect(
714 unused_variables,
715 reason = "The parameters here are intentionally unused by the default implementation; however, putting underscores here will result in the underscores being copied by rust-analyzer's tab completion."
716 )]
717 fn __register(registry: &mut TypeRegistry) {}
718 }
719
720 impl<T: GetTypeRegistration> RegisterForReflection for T {
721 fn __register(registry: &mut TypeRegistry) {
722 registry.register::<T>();
723 }
724 }
725
726 impl RegisterForReflection for DynamicEnum {}
727
728 impl RegisterForReflection for DynamicTupleStruct {}
729
730 impl RegisterForReflection for DynamicStruct {}
731
732 impl RegisterForReflection for DynamicMap {}
733
734 impl RegisterForReflection for DynamicList {}
735
736 impl RegisterForReflection for DynamicArray {}
737
738 impl RegisterForReflection for DynamicTuple {}
739
740 #[cfg(feature = "auto_register")]
742 pub mod auto_register {
743 pub use super::*;
744
745 #[cfg(all(
746 not(feature = "auto_register_inventory"),
747 not(feature = "auto_register_static")
748 ))]
749 compile_error!(
750 "Choosing a backend is required for automatic reflect registration. Please enable either the \"auto_register_inventory\" or the \"auto_register_static\" feature."
751 );
752
753 #[cfg(all(
755 not(feature = "auto_register_static"),
756 feature = "auto_register_inventory"
757 ))]
758 mod __automatic_type_registration_impl {
759 use super::*;
760
761 pub use inventory;
762
763 pub struct AutomaticReflectRegistrations(pub fn(&mut TypeRegistry));
765
766 pub fn register_types(registry: &mut TypeRegistry) {
768 #[cfg(target_family = "wasm")]
769 wasm_support::init();
770 for registration_fn in inventory::iter::<AutomaticReflectRegistrations> {
771 registration_fn.0(registry);
772 }
773 }
774
775 inventory::collect!(AutomaticReflectRegistrations);
776
777 #[cfg(target_family = "wasm")]
778 mod wasm_support {
779 use bevy_platform::sync::atomic::{AtomicBool, Ordering};
780
781 static INIT_DONE: AtomicBool = AtomicBool::new(false);
782
783 #[expect(unsafe_code, reason = "This function is generated by linker.")]
784 unsafe extern "C" {
785 fn __wasm_call_ctors();
786 }
787
788 pub fn init() {
790 if INIT_DONE.swap(true, Ordering::Relaxed) {
791 return;
792 };
793 #[expect(
798 unsafe_code,
799 reason = "This function must be called to use inventory on wasm."
800 )]
801 unsafe {
802 __wasm_call_ctors();
803 }
804 }
805 }
806 }
807
808 #[cfg(feature = "auto_register_static")]
810 mod __automatic_type_registration_impl {
811 use super::*;
812 use alloc::vec::Vec;
813 use bevy_platform::sync::Mutex;
814
815 static REGISTRATION_FNS: Mutex<Vec<fn(&mut TypeRegistry)>> = Mutex::new(Vec::new());
816
817 pub fn push_registration_fn(registration_fn: fn(&mut TypeRegistry)) {
819 REGISTRATION_FNS.lock().unwrap().push(registration_fn);
820 }
821
822 pub fn register_types(registry: &mut TypeRegistry) {
824 for func in REGISTRATION_FNS.lock().unwrap().iter() {
825 (func)(registry);
826 }
827 }
828 }
829
830 #[cfg(any(feature = "auto_register_static", feature = "auto_register_inventory"))]
831 pub use __automatic_type_registration_impl::*;
832 }
833}
834
835#[cfg(test)]
836#[expect(
837 clippy::approx_constant,
838 reason = "We don't need the exact value of Pi here."
839)]
840mod tests {
841 use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
842 use alloc::{
843 borrow::Cow,
844 boxed::Box,
845 format,
846 string::{String, ToString},
847 vec,
848 vec::Vec,
849 };
850 use bevy_platform::collections::HashMap;
851 use core::{
852 any::TypeId,
853 fmt::{Debug, Formatter},
854 hash::Hash,
855 marker::PhantomData,
856 };
857 use disqualified::ShortName;
858 use ron::{
859 ser::{to_string_pretty, PrettyConfig},
860 Deserializer,
861 };
862 use static_assertions::{assert_impl_all, assert_not_impl_all};
863
864 use super::{prelude::*, *};
865 use crate::{
866 serde::{ReflectDeserializer, ReflectSerializer},
867 utility::GenericTypePathCell,
868 };
869
870 #[test]
871 fn try_apply_should_detect_kinds() {
872 #[derive(Reflect, Debug)]
873 struct Struct {
874 a: u32,
875 b: f32,
876 }
877
878 #[derive(Reflect, Debug)]
879 enum Enum {
880 A,
881 B(u32),
882 }
883
884 let mut struct_target = Struct {
885 a: 0xDEADBEEF,
886 b: 3.14,
887 };
888
889 let mut enum_target = Enum::A;
890
891 let array_src = [8, 0, 8];
892
893 let result = struct_target.try_apply(&enum_target);
894 assert!(
895 matches!(
896 result,
897 Err(ApplyError::MismatchedKinds {
898 from_kind: ReflectKind::Enum,
899 to_kind: ReflectKind::Struct
900 })
901 ),
902 "result was {result:?}"
903 );
904
905 let result = enum_target.try_apply(&array_src);
906 assert!(
907 matches!(
908 result,
909 Err(ApplyError::MismatchedKinds {
910 from_kind: ReflectKind::Array,
911 to_kind: ReflectKind::Enum
912 })
913 ),
914 "result was {result:?}"
915 );
916 }
917
918 #[test]
919 fn reflect_struct() {
920 #[derive(Reflect)]
921 struct Foo {
922 a: u32,
923 b: f32,
924 c: Bar,
925 }
926 #[derive(Reflect)]
927 struct Bar {
928 x: u32,
929 }
930
931 let mut foo = Foo {
932 a: 42,
933 b: 3.14,
934 c: Bar { x: 1 },
935 };
936
937 let a = *foo.get_field::<u32>("a").unwrap();
938 assert_eq!(a, 42);
939
940 *foo.get_field_mut::<u32>("a").unwrap() += 1;
941 assert_eq!(foo.a, 43);
942
943 let bar = foo.get_field::<Bar>("c").unwrap();
944 assert_eq!(bar.x, 1);
945
946 let c = foo.field("c").unwrap();
948 let value = c.reflect_ref().as_struct().unwrap();
949 assert_eq!(*value.get_field::<u32>("x").unwrap(), 1);
950
951 let mut dynamic_struct = DynamicStruct::default();
953 dynamic_struct.insert("a", 123u32);
954 dynamic_struct.insert("should_be_ignored", 456);
955
956 foo.apply(&dynamic_struct);
957 assert_eq!(foo.a, 123);
958 }
959
960 #[test]
961 fn reflect_map() {
962 #[derive(Reflect, Hash)]
963 #[reflect(Hash)]
964 struct Foo {
965 a: u32,
966 b: String,
967 }
968
969 let key_a = Foo {
970 a: 1,
971 b: "k1".to_string(),
972 };
973
974 let key_b = Foo {
975 a: 1,
976 b: "k1".to_string(),
977 };
978
979 let key_c = Foo {
980 a: 3,
981 b: "k3".to_string(),
982 };
983
984 let mut map = DynamicMap::default();
985 map.insert(key_a, 10u32);
986 assert_eq!(
987 10,
988 *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
989 );
990 assert!(map.get(&key_c).is_none());
991 *map.get_mut(&key_b)
992 .unwrap()
993 .try_downcast_mut::<u32>()
994 .unwrap() = 20;
995 assert_eq!(
996 20,
997 *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
998 );
999 }
1000
1001 #[test]
1002 fn reflect_unit_struct() {
1003 #[derive(Reflect)]
1004 struct Foo(u32, u64);
1005
1006 let mut foo = Foo(1, 2);
1007 assert_eq!(1, *foo.get_field::<u32>(0).unwrap());
1008 assert_eq!(2, *foo.get_field::<u64>(1).unwrap());
1009
1010 let mut patch = DynamicTupleStruct::default();
1011 patch.insert(3u32);
1012 patch.insert(4u64);
1013 assert_eq!(
1014 3,
1015 *patch.field(0).unwrap().try_downcast_ref::<u32>().unwrap()
1016 );
1017 assert_eq!(
1018 4,
1019 *patch.field(1).unwrap().try_downcast_ref::<u64>().unwrap()
1020 );
1021
1022 foo.apply(&patch);
1023 assert_eq!(3, foo.0);
1024 assert_eq!(4, foo.1);
1025
1026 let mut iter = patch.iter_fields();
1027 assert_eq!(3, *iter.next().unwrap().try_downcast_ref::<u32>().unwrap());
1028 assert_eq!(4, *iter.next().unwrap().try_downcast_ref::<u64>().unwrap());
1029 }
1030
1031 #[test]
1032 #[should_panic(
1033 expected = "the given key of type `bevy_reflect::tests::Foo` does not support hashing"
1034 )]
1035 fn reflect_map_no_hash() {
1036 #[derive(Reflect)]
1037 struct Foo {
1038 a: u32,
1039 }
1040
1041 let foo = Foo { a: 1 };
1042 assert!(foo.reflect_hash().is_none());
1043
1044 let mut map = DynamicMap::default();
1045 map.insert(foo, 10u32);
1046 }
1047
1048 #[test]
1049 #[should_panic(
1050 expected = "the dynamic type `bevy_reflect::DynamicStruct` (representing `bevy_reflect::tests::Foo`) does not support hashing"
1051 )]
1052 fn reflect_map_no_hash_dynamic_representing() {
1053 #[derive(Reflect, Hash)]
1054 #[reflect(Hash)]
1055 struct Foo {
1056 a: u32,
1057 }
1058
1059 let foo = Foo { a: 1 };
1060 assert!(foo.reflect_hash().is_some());
1061 let dynamic = foo.to_dynamic_struct();
1062
1063 let mut map = DynamicMap::default();
1064 map.insert(dynamic, 11u32);
1065 }
1066
1067 #[test]
1068 #[should_panic(
1069 expected = "the dynamic type `bevy_reflect::DynamicStruct` does not support hashing"
1070 )]
1071 fn reflect_map_no_hash_dynamic() {
1072 #[allow(
1073 clippy::allow_attributes,
1074 dead_code,
1075 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1076 )]
1077 #[derive(Reflect, Hash)]
1078 #[reflect(Hash)]
1079 struct Foo {
1080 a: u32,
1081 }
1082
1083 let mut dynamic = DynamicStruct::default();
1084 dynamic.insert("a", 4u32);
1085 assert!(dynamic.reflect_hash().is_none());
1086
1087 let mut map = DynamicMap::default();
1088 map.insert(dynamic, 11u32);
1089 }
1090
1091 #[test]
1092 fn reflect_ignore() {
1093 #[derive(Reflect)]
1094 struct Foo {
1095 a: u32,
1096 #[reflect(ignore)]
1097 _b: u32,
1098 }
1099
1100 let foo = Foo { a: 1, _b: 2 };
1101
1102 let values: Vec<u32> = foo
1103 .iter_fields()
1104 .map(|value| *value.try_downcast_ref::<u32>().unwrap())
1105 .collect();
1106 assert_eq!(values, vec![1]);
1107 }
1108
1109 #[test]
1123 fn should_reflect_generic() {
1124 struct FakeString {}
1125
1126 impl core::ops::Add<FakeString> for String {
1128 type Output = Self;
1129 fn add(self, _rhs: FakeString) -> Self::Output {
1130 unreachable!()
1131 }
1132 }
1133
1134 #[expect(
1135 dead_code,
1136 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1137 )]
1138 #[derive(Reflect)]
1139 struct Foo<A>(A);
1140
1141 #[expect(
1142 dead_code,
1143 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1144 )]
1145 #[derive(Reflect)]
1146 struct Bar<A, B>(A, B);
1147
1148 #[expect(
1149 dead_code,
1150 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1151 )]
1152 #[derive(Reflect)]
1153 struct Baz<A, B, C>(A, B, C);
1154 }
1155
1156 #[test]
1157 fn should_reflect_clone() {
1158 #[derive(Reflect, Debug, PartialEq)]
1160 struct Foo(usize);
1161
1162 let value = Foo(123);
1163 let clone = value.reflect_clone().expect("should reflect_clone struct");
1164 assert_eq!(value, clone.take::<Foo>().unwrap());
1165
1166 let foo = (123, 4.56);
1168 let clone = foo.reflect_clone().expect("should reflect_clone tuple");
1169 assert_eq!(foo, clone.take::<(u32, f32)>().unwrap());
1170 }
1171
1172 #[test]
1173 fn should_reflect_clone_generic_type() {
1174 #[derive(Reflect, Debug, PartialEq)]
1175 struct Foo<T, U>(T, #[reflect(ignore, clone)] PhantomData<U>);
1176 #[derive(TypePath, Debug, PartialEq)]
1177 struct Bar;
1178
1179 let value = Foo::<usize, Bar>(123, PhantomData);
1182 let clone = value
1183 .reflect_clone()
1184 .expect("should reflect_clone generic struct");
1185 assert_eq!(value, clone.take::<Foo<usize, Bar>>().unwrap());
1186 }
1187
1188 #[test]
1189 fn should_reflect_clone_with_clone() {
1190 #[expect(
1193 dead_code,
1194 reason = "if things are working correctly, this function should never be called"
1195 )]
1196 fn custom_clone(_value: &usize) -> usize {
1197 panic!("should not be called");
1198 }
1199
1200 #[derive(Reflect, Clone, Debug, PartialEq)]
1202 #[reflect(Clone)]
1203 struct Foo(#[reflect(clone = "custom_clone")] usize);
1204
1205 let value = Foo(123);
1206 let clone = value
1207 .reflect_clone()
1208 .expect("should reflect_clone tuple struct");
1209 assert_eq!(value, clone.take::<Foo>().unwrap());
1210
1211 #[derive(Reflect, Clone, Debug, PartialEq)]
1213 #[reflect(Clone)]
1214 struct Bar {
1215 #[reflect(clone = "custom_clone")]
1216 value: usize,
1217 }
1218
1219 let value = Bar { value: 123 };
1220 let clone = value.reflect_clone().expect("should reflect_clone struct");
1221 assert_eq!(value, clone.take::<Bar>().unwrap());
1222
1223 #[derive(Reflect, Clone, Debug, PartialEq)]
1225 #[reflect(Clone)]
1226 enum Baz {
1227 Unit,
1228 Tuple(#[reflect(clone = "custom_clone")] usize),
1229 Struct {
1230 #[reflect(clone = "custom_clone")]
1231 value: usize,
1232 },
1233 }
1234
1235 let value = Baz::Unit;
1236 let clone = value
1237 .reflect_clone()
1238 .expect("should reflect_clone unit variant");
1239 assert_eq!(value, clone.take::<Baz>().unwrap());
1240
1241 let value = Baz::Tuple(123);
1242 let clone = value
1243 .reflect_clone()
1244 .expect("should reflect_clone tuple variant");
1245 assert_eq!(value, clone.take::<Baz>().unwrap());
1246
1247 let value = Baz::Struct { value: 123 };
1248 let clone = value
1249 .reflect_clone()
1250 .expect("should reflect_clone struct variant");
1251 assert_eq!(value, clone.take::<Baz>().unwrap());
1252 }
1253
1254 #[test]
1255 fn should_custom_reflect_clone() {
1256 #[derive(Reflect, Debug, PartialEq)]
1257 #[reflect(Clone(clone_foo))]
1258 struct Foo(usize);
1259
1260 fn clone_foo(foo: &Foo) -> Foo {
1261 Foo(foo.0 + 198)
1262 }
1263
1264 let foo = Foo(123);
1265 let clone = foo.reflect_clone().unwrap();
1266 assert_eq!(Foo(321), clone.take::<Foo>().unwrap());
1267 }
1268
1269 #[test]
1270 fn should_not_clone_ignored_fields() {
1271 #[derive(Reflect, Clone, Debug, PartialEq)]
1273 struct Foo(#[reflect(ignore)] usize);
1274
1275 let foo = Foo(123);
1276 let clone = foo.reflect_clone();
1277 assert_eq!(
1278 clone.unwrap_err(),
1279 ReflectCloneError::FieldNotCloneable {
1280 field: FieldId::Unnamed(0),
1281 variant: None,
1282 container_type_path: Cow::Borrowed(Foo::type_path()),
1283 }
1284 );
1285
1286 #[derive(Reflect, Clone, Debug, PartialEq)]
1288 struct Bar {
1289 #[reflect(ignore)]
1290 value: usize,
1291 }
1292
1293 let bar = Bar { value: 123 };
1294 let clone = bar.reflect_clone();
1295 assert_eq!(
1296 clone.unwrap_err(),
1297 ReflectCloneError::FieldNotCloneable {
1298 field: FieldId::Named(Cow::Borrowed("value")),
1299 variant: None,
1300 container_type_path: Cow::Borrowed(Bar::type_path()),
1301 }
1302 );
1303
1304 #[derive(Reflect, Clone, Debug, PartialEq)]
1306 enum Baz {
1307 Tuple(#[reflect(ignore)] usize),
1308 Struct {
1309 #[reflect(ignore)]
1310 value: usize,
1311 },
1312 }
1313
1314 let baz = Baz::Tuple(123);
1315 let clone = baz.reflect_clone();
1316 assert_eq!(
1317 clone.unwrap_err(),
1318 ReflectCloneError::FieldNotCloneable {
1319 field: FieldId::Unnamed(0),
1320 variant: Some(Cow::Borrowed("Tuple")),
1321 container_type_path: Cow::Borrowed(Baz::type_path()),
1322 }
1323 );
1324
1325 let baz = Baz::Struct { value: 123 };
1326 let clone = baz.reflect_clone();
1327 assert_eq!(
1328 clone.unwrap_err(),
1329 ReflectCloneError::FieldNotCloneable {
1330 field: FieldId::Named(Cow::Borrowed("value")),
1331 variant: Some(Cow::Borrowed("Struct")),
1332 container_type_path: Cow::Borrowed(Baz::type_path()),
1333 }
1334 );
1335 }
1336
1337 #[test]
1338 fn should_clone_ignored_fields_with_clone_attributes() {
1339 #[derive(Reflect, Clone, Debug, PartialEq)]
1340 struct Foo(#[reflect(ignore, clone)] usize);
1341
1342 let foo = Foo(123);
1343 let clone = foo.reflect_clone().unwrap();
1344 assert_eq!(Foo(123), clone.take::<Foo>().unwrap());
1345
1346 #[derive(Reflect, Clone, Debug, PartialEq)]
1347 struct Bar(#[reflect(ignore, clone = "clone_usize")] usize);
1348
1349 fn clone_usize(this: &usize) -> usize {
1350 *this + 198
1351 }
1352
1353 let bar = Bar(123);
1354 let clone = bar.reflect_clone().unwrap();
1355 assert_eq!(Bar(321), clone.take::<Bar>().unwrap());
1356 }
1357
1358 #[test]
1359 fn should_composite_reflect_clone() {
1360 #[derive(Reflect, Debug, PartialEq)]
1361 enum MyEnum {
1362 Unit,
1363 Tuple(
1364 Foo,
1365 #[reflect(ignore, clone)] Bar,
1366 #[reflect(clone = "clone_baz")] Baz,
1367 ),
1368 Struct {
1369 foo: Foo,
1370 #[reflect(ignore, clone)]
1371 bar: Bar,
1372 #[reflect(clone = "clone_baz")]
1373 baz: Baz,
1374 },
1375 }
1376
1377 #[derive(Reflect, Debug, PartialEq)]
1378 struct Foo {
1379 #[reflect(clone = "clone_bar")]
1380 bar: Bar,
1381 baz: Baz,
1382 }
1383
1384 #[derive(Reflect, Default, Clone, Debug, PartialEq)]
1385 #[reflect(Clone)]
1386 struct Bar(String);
1387
1388 #[derive(Reflect, Debug, PartialEq)]
1389 struct Baz(String);
1390
1391 fn clone_bar(bar: &Bar) -> Bar {
1392 Bar(format!("{}!", bar.0))
1393 }
1394
1395 fn clone_baz(baz: &Baz) -> Baz {
1396 Baz(format!("{}!", baz.0))
1397 }
1398
1399 let my_enum = MyEnum::Unit;
1400 let clone = my_enum.reflect_clone().unwrap();
1401 assert_eq!(MyEnum::Unit, clone.take::<MyEnum>().unwrap());
1402
1403 let my_enum = MyEnum::Tuple(
1404 Foo {
1405 bar: Bar("bar".to_string()),
1406 baz: Baz("baz".to_string()),
1407 },
1408 Bar("bar".to_string()),
1409 Baz("baz".to_string()),
1410 );
1411 let clone = my_enum.reflect_clone().unwrap();
1412 assert_eq!(
1413 MyEnum::Tuple(
1414 Foo {
1415 bar: Bar("bar!".to_string()),
1416 baz: Baz("baz".to_string()),
1417 },
1418 Bar("bar".to_string()),
1419 Baz("baz!".to_string()),
1420 ),
1421 clone.take::<MyEnum>().unwrap()
1422 );
1423
1424 let my_enum = MyEnum::Struct {
1425 foo: Foo {
1426 bar: Bar("bar".to_string()),
1427 baz: Baz("baz".to_string()),
1428 },
1429 bar: Bar("bar".to_string()),
1430 baz: Baz("baz".to_string()),
1431 };
1432 let clone = my_enum.reflect_clone().unwrap();
1433 assert_eq!(
1434 MyEnum::Struct {
1435 foo: Foo {
1436 bar: Bar("bar!".to_string()),
1437 baz: Baz("baz".to_string()),
1438 },
1439 bar: Bar("bar".to_string()),
1440 baz: Baz("baz!".to_string()),
1441 },
1442 clone.take::<MyEnum>().unwrap()
1443 );
1444 }
1445
1446 #[test]
1447 fn should_call_from_reflect_dynamically() {
1448 #[derive(Reflect)]
1449 struct MyStruct {
1450 foo: usize,
1451 }
1452
1453 let mut registry = TypeRegistry::default();
1455 registry.register::<MyStruct>();
1456
1457 let type_id = TypeId::of::<MyStruct>();
1459 let rfr = registry
1460 .get_type_data::<ReflectFromReflect>(type_id)
1461 .expect("the FromReflect trait should be registered");
1462
1463 let mut dynamic_struct = DynamicStruct::default();
1465 dynamic_struct.insert("foo", 123usize);
1466 let reflected = rfr
1467 .from_reflect(&dynamic_struct)
1468 .expect("the type should be properly reflected");
1469
1470 let expected = MyStruct { foo: 123 };
1472 assert!(expected
1473 .reflect_partial_eq(reflected.as_partial_reflect())
1474 .unwrap_or_default());
1475 let not_expected = MyStruct { foo: 321 };
1476 assert!(!not_expected
1477 .reflect_partial_eq(reflected.as_partial_reflect())
1478 .unwrap_or_default());
1479 }
1480
1481 #[test]
1482 fn from_reflect_should_allow_ignored_unnamed_fields() {
1483 #[derive(Reflect, Eq, PartialEq, Debug)]
1484 struct MyTupleStruct(i8, #[reflect(ignore)] i16, i32);
1485
1486 let expected = MyTupleStruct(1, 0, 3);
1487
1488 let mut dyn_tuple_struct = DynamicTupleStruct::default();
1489 dyn_tuple_struct.insert(1_i8);
1490 dyn_tuple_struct.insert(3_i32);
1491 let my_tuple_struct = <MyTupleStruct as FromReflect>::from_reflect(&dyn_tuple_struct);
1492
1493 assert_eq!(Some(expected), my_tuple_struct);
1494
1495 #[derive(Reflect, Eq, PartialEq, Debug)]
1496 enum MyEnum {
1497 Tuple(i8, #[reflect(ignore)] i16, i32),
1498 }
1499
1500 let expected = MyEnum::Tuple(1, 0, 3);
1501
1502 let mut dyn_tuple = DynamicTuple::default();
1503 dyn_tuple.insert(1_i8);
1504 dyn_tuple.insert(3_i32);
1505
1506 let mut dyn_enum = DynamicEnum::default();
1507 dyn_enum.set_variant("Tuple", dyn_tuple);
1508
1509 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1510
1511 assert_eq!(Some(expected), my_enum);
1512 }
1513
1514 #[test]
1515 fn from_reflect_should_use_default_field_attributes() {
1516 #[derive(Reflect, Eq, PartialEq, Debug)]
1517 struct MyStruct {
1518 #[reflect(default)]
1521 foo: String,
1522
1523 #[reflect(ignore)]
1525 #[reflect(default = "get_bar_default")]
1526 bar: NotReflect,
1527
1528 #[reflect(ignore, default = "get_bar_default")]
1530 baz: NotReflect,
1531 }
1532
1533 #[derive(Eq, PartialEq, Debug)]
1534 struct NotReflect(usize);
1535
1536 fn get_bar_default() -> NotReflect {
1537 NotReflect(123)
1538 }
1539
1540 let expected = MyStruct {
1541 foo: String::default(),
1542 bar: NotReflect(123),
1543 baz: NotReflect(123),
1544 };
1545
1546 let dyn_struct = DynamicStruct::default();
1547 let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
1548
1549 assert_eq!(Some(expected), my_struct);
1550 }
1551
1552 #[test]
1553 fn from_reflect_should_use_default_variant_field_attributes() {
1554 #[derive(Reflect, Eq, PartialEq, Debug)]
1555 enum MyEnum {
1556 Foo(#[reflect(default)] String),
1557 Bar {
1558 #[reflect(default = "get_baz_default")]
1559 #[reflect(ignore)]
1560 baz: usize,
1561 },
1562 }
1563
1564 fn get_baz_default() -> usize {
1565 123
1566 }
1567
1568 let expected = MyEnum::Foo(String::default());
1569
1570 let dyn_enum = DynamicEnum::new("Foo", DynamicTuple::default());
1571 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1572
1573 assert_eq!(Some(expected), my_enum);
1574
1575 let expected = MyEnum::Bar {
1576 baz: get_baz_default(),
1577 };
1578
1579 let dyn_enum = DynamicEnum::new("Bar", DynamicStruct::default());
1580 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1581
1582 assert_eq!(Some(expected), my_enum);
1583 }
1584
1585 #[test]
1586 fn from_reflect_should_use_default_container_attribute() {
1587 #[derive(Reflect, Eq, PartialEq, Debug)]
1588 #[reflect(Default)]
1589 struct MyStruct {
1590 foo: String,
1591 #[reflect(ignore)]
1592 bar: usize,
1593 }
1594
1595 impl Default for MyStruct {
1596 fn default() -> Self {
1597 Self {
1598 foo: String::from("Hello"),
1599 bar: 123,
1600 }
1601 }
1602 }
1603
1604 let expected = MyStruct {
1605 foo: String::from("Hello"),
1606 bar: 123,
1607 };
1608
1609 let dyn_struct = DynamicStruct::default();
1610 let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
1611
1612 assert_eq!(Some(expected), my_struct);
1613 }
1614
1615 #[test]
1616 fn reflect_complex_patch() {
1617 #[derive(Reflect, Eq, PartialEq, Debug)]
1618 #[reflect(PartialEq)]
1619 struct Foo {
1620 a: u32,
1621 #[reflect(ignore)]
1622 _b: u32,
1623 c: Vec<isize>,
1624 d: HashMap<usize, i8>,
1625 e: Bar,
1626 f: (i32, Vec<isize>, Bar),
1627 g: Vec<(Baz, HashMap<usize, Bar>)>,
1628 h: [u32; 2],
1629 }
1630
1631 #[derive(Reflect, Eq, PartialEq, Clone, Debug)]
1632 #[reflect(PartialEq)]
1633 struct Bar {
1634 x: u32,
1635 }
1636
1637 #[derive(Reflect, Eq, PartialEq, Debug)]
1638 struct Baz(String);
1639
1640 let mut hash_map = <HashMap<_, _>>::default();
1641 hash_map.insert(1, 1);
1642 hash_map.insert(2, 2);
1643
1644 let mut hash_map_baz = <HashMap<_, _>>::default();
1645 hash_map_baz.insert(1, Bar { x: 0 });
1646
1647 let mut foo = Foo {
1648 a: 1,
1649 _b: 1,
1650 c: vec![1, 2],
1651 d: hash_map,
1652 e: Bar { x: 1 },
1653 f: (1, vec![1, 2], Bar { x: 1 }),
1654 g: vec![(Baz("string".to_string()), hash_map_baz)],
1655 h: [2; 2],
1656 };
1657
1658 let mut foo_patch = DynamicStruct::default();
1659 foo_patch.insert("a", 2u32);
1660 foo_patch.insert("b", 2u32); let mut list = DynamicList::default();
1663 list.push(3isize);
1664 list.push(4isize);
1665 list.push(5isize);
1666 foo_patch.insert("c", list.to_dynamic_list());
1667
1668 let mut map = DynamicMap::default();
1669 map.insert(2usize, 3i8);
1670 map.insert(3usize, 4i8);
1671 foo_patch.insert("d", map);
1672
1673 let mut bar_patch = DynamicStruct::default();
1674 bar_patch.insert("x", 2u32);
1675 foo_patch.insert("e", bar_patch.to_dynamic_struct());
1676
1677 let mut tuple = DynamicTuple::default();
1678 tuple.insert(2i32);
1679 tuple.insert(list);
1680 tuple.insert(bar_patch);
1681 foo_patch.insert("f", tuple);
1682
1683 let mut composite = DynamicList::default();
1684 composite.push({
1685 let mut tuple = DynamicTuple::default();
1686 tuple.insert({
1687 let mut tuple_struct = DynamicTupleStruct::default();
1688 tuple_struct.insert("new_string".to_string());
1689 tuple_struct
1690 });
1691 tuple.insert({
1692 let mut map = DynamicMap::default();
1693 map.insert(1usize, {
1694 let mut struct_ = DynamicStruct::default();
1695 struct_.insert("x", 7u32);
1696 struct_
1697 });
1698 map
1699 });
1700 tuple
1701 });
1702 foo_patch.insert("g", composite);
1703
1704 let array = DynamicArray::from_iter([2u32, 2u32]);
1705 foo_patch.insert("h", array);
1706
1707 foo.apply(&foo_patch);
1708
1709 let mut hash_map = <HashMap<_, _>>::default();
1710 hash_map.insert(2, 3);
1711 hash_map.insert(3, 4);
1712
1713 let mut hash_map_baz = <HashMap<_, _>>::default();
1714 hash_map_baz.insert(1, Bar { x: 7 });
1715
1716 let expected_foo = Foo {
1717 a: 2,
1718 _b: 1,
1719 c: vec![3, 4, 5],
1720 d: hash_map,
1721 e: Bar { x: 2 },
1722 f: (2, vec![3, 4, 5], Bar { x: 2 }),
1723 g: vec![(Baz("new_string".to_string()), hash_map_baz.clone())],
1724 h: [2; 2],
1725 };
1726
1727 assert_eq!(foo, expected_foo);
1728
1729 let new_foo = Foo::from_reflect(&foo_patch)
1730 .expect("error while creating a concrete type from a dynamic type");
1731
1732 let mut hash_map = <HashMap<_, _>>::default();
1733 hash_map.insert(2, 3);
1734 hash_map.insert(3, 4);
1735
1736 let expected_new_foo = Foo {
1737 a: 2,
1738 _b: 0,
1739 c: vec![3, 4, 5],
1740 d: hash_map,
1741 e: Bar { x: 2 },
1742 f: (2, vec![3, 4, 5], Bar { x: 2 }),
1743 g: vec![(Baz("new_string".to_string()), hash_map_baz)],
1744 h: [2; 2],
1745 };
1746
1747 assert_eq!(new_foo, expected_new_foo);
1748 }
1749
1750 #[test]
1751 fn should_auto_register_fields() {
1752 #[derive(Reflect)]
1753 struct Foo {
1754 bar: Bar,
1755 }
1756
1757 #[derive(Reflect)]
1758 enum Bar {
1759 Variant(Baz),
1760 }
1761
1762 #[derive(Reflect)]
1763 struct Baz(usize);
1764
1765 let mut registry = TypeRegistry::empty();
1767 registry.register::<Foo>();
1768
1769 assert!(
1770 registry.contains(TypeId::of::<Bar>()),
1771 "registry should contain auto-registered `Bar` from `Foo`"
1772 );
1773
1774 let mut registry = TypeRegistry::empty();
1776 registry.register::<Option<Foo>>();
1777
1778 assert!(
1779 registry.contains(TypeId::of::<Bar>()),
1780 "registry should contain auto-registered `Bar` from `Option<Foo>`"
1781 );
1782
1783 let mut registry = TypeRegistry::empty();
1785 registry.register::<(Foo, Foo)>();
1786
1787 assert!(
1788 registry.contains(TypeId::of::<Bar>()),
1789 "registry should contain auto-registered `Bar` from `(Foo, Foo)`"
1790 );
1791
1792 let mut registry = TypeRegistry::empty();
1794 registry.register::<[Foo; 3]>();
1795
1796 assert!(
1797 registry.contains(TypeId::of::<Bar>()),
1798 "registry should contain auto-registered `Bar` from `[Foo; 3]`"
1799 );
1800
1801 let mut registry = TypeRegistry::empty();
1803 registry.register::<Vec<Foo>>();
1804
1805 assert!(
1806 registry.contains(TypeId::of::<Bar>()),
1807 "registry should contain auto-registered `Bar` from `Vec<Foo>`"
1808 );
1809
1810 let mut registry = TypeRegistry::empty();
1812 registry.register::<HashMap<i32, Foo>>();
1813
1814 assert!(
1815 registry.contains(TypeId::of::<Bar>()),
1816 "registry should contain auto-registered `Bar` from `HashMap<i32, Foo>`"
1817 );
1818 }
1819
1820 #[test]
1821 fn should_allow_dynamic_fields() {
1822 #[derive(Reflect)]
1823 #[reflect(from_reflect = false)]
1824 struct MyStruct(
1825 DynamicEnum,
1826 DynamicTupleStruct,
1827 DynamicStruct,
1828 DynamicMap,
1829 DynamicList,
1830 DynamicArray,
1831 DynamicTuple,
1832 i32,
1833 );
1834
1835 assert_impl_all!(MyStruct: Reflect, GetTypeRegistration);
1836
1837 let mut registry = TypeRegistry::empty();
1838 registry.register::<MyStruct>();
1839
1840 assert_eq!(2, registry.iter().count());
1841 assert!(registry.contains(TypeId::of::<MyStruct>()));
1842 assert!(registry.contains(TypeId::of::<i32>()));
1843 }
1844
1845 #[test]
1846 fn should_not_auto_register_existing_types() {
1847 #[derive(Reflect)]
1848 struct Foo {
1849 bar: Bar,
1850 }
1851
1852 #[derive(Reflect, Default)]
1853 struct Bar(usize);
1854
1855 let mut registry = TypeRegistry::empty();
1856 registry.register::<Bar>();
1857 registry.register_type_data::<Bar, ReflectDefault>();
1858 registry.register::<Foo>();
1859
1860 assert!(
1861 registry
1862 .get_type_data::<ReflectDefault>(TypeId::of::<Bar>())
1863 .is_some(),
1864 "registry should contain existing registration for `Bar`"
1865 );
1866 }
1867
1868 #[test]
1869 fn reflect_serialize() {
1870 #[derive(Reflect)]
1871 struct Foo {
1872 a: u32,
1873 #[reflect(ignore)]
1874 _b: u32,
1875 c: Vec<isize>,
1876 d: HashMap<usize, i8>,
1877 e: Bar,
1878 f: String,
1879 g: (i32, Vec<isize>, Bar),
1880 h: [u32; 2],
1881 }
1882
1883 #[derive(Reflect, Serialize, Deserialize)]
1884 #[reflect(Serialize, Deserialize)]
1885 struct Bar {
1886 x: u32,
1887 }
1888
1889 let mut hash_map = <HashMap<_, _>>::default();
1890 hash_map.insert(1, 1);
1891 hash_map.insert(2, 2);
1892 let foo = Foo {
1893 a: 1,
1894 _b: 1,
1895 c: vec![1, 2],
1896 d: hash_map,
1897 e: Bar { x: 1 },
1898 f: "hi".to_string(),
1899 g: (1, vec![1, 2], Bar { x: 1 }),
1900 h: [2; 2],
1901 };
1902
1903 let mut registry = TypeRegistry::default();
1904 registry.register::<u32>();
1905 registry.register::<i8>();
1906 registry.register::<i32>();
1907 registry.register::<usize>();
1908 registry.register::<isize>();
1909 registry.register::<Foo>();
1910 registry.register::<Bar>();
1911 registry.register::<String>();
1912 registry.register::<Vec<isize>>();
1913 registry.register::<HashMap<usize, i8>>();
1914 registry.register::<(i32, Vec<isize>, Bar)>();
1915 registry.register::<[u32; 2]>();
1916
1917 let serializer = ReflectSerializer::new(&foo, ®istry);
1918 let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
1919
1920 let mut deserializer = Deserializer::from_str(&serialized).unwrap();
1921 let reflect_deserializer = ReflectDeserializer::new(®istry);
1922 let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
1923 let roundtrip_foo = Foo::from_reflect(value.as_partial_reflect()).unwrap();
1924
1925 assert!(foo.reflect_partial_eq(&roundtrip_foo).unwrap());
1926 }
1927
1928 #[test]
1929 fn reflect_downcast() {
1930 #[derive(Reflect, Clone, Debug, PartialEq)]
1931 struct Bar {
1932 y: u8,
1933 }
1934
1935 #[derive(Reflect, Clone, Debug, PartialEq)]
1936 struct Foo {
1937 x: i32,
1938 s: String,
1939 b: Bar,
1940 u: usize,
1941 t: ([f32; 3], String),
1942 v: Cow<'static, str>,
1943 w: Cow<'static, [u8]>,
1944 }
1945
1946 let foo = Foo {
1947 x: 123,
1948 s: "String".to_string(),
1949 b: Bar { y: 255 },
1950 u: 1111111111111,
1951 t: ([3.0, 2.0, 1.0], "Tuple String".to_string()),
1952 v: Cow::Owned("Cow String".to_string()),
1953 w: Cow::Owned(vec![1, 2, 3]),
1954 };
1955
1956 let foo2: Box<dyn Reflect> = Box::new(foo.clone());
1957
1958 assert_eq!(foo, *foo2.downcast::<Foo>().unwrap());
1959 }
1960
1961 #[test]
1962 fn should_drain_fields() {
1963 let array_value: Box<dyn Array> = Box::new([123_i32, 321_i32]);
1964 let fields = array_value.drain();
1965 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1966 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1967
1968 let mut list_value: Box<dyn List> = Box::new(vec![123_i32, 321_i32]);
1969 let fields = list_value.drain();
1970 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1971 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1972
1973 let tuple_value: Box<dyn Tuple> = Box::new((123_i32, 321_i32));
1974 let fields = tuple_value.drain();
1975 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1976 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1977
1978 let mut map_value: Box<dyn Map> =
1979 Box::new([(123_i32, 321_i32)].into_iter().collect::<HashMap<_, _>>());
1980 let fields = map_value.drain();
1981 assert!(fields[0].0.reflect_partial_eq(&123_i32).unwrap_or_default());
1982 assert!(fields[0].1.reflect_partial_eq(&321_i32).unwrap_or_default());
1983 }
1984
1985 #[test]
1986 fn reflect_take() {
1987 #[derive(Reflect, Debug, PartialEq)]
1988 #[reflect(PartialEq)]
1989 struct Bar {
1990 x: u32,
1991 }
1992
1993 let x: Box<dyn Reflect> = Box::new(Bar { x: 2 });
1994 let y = x.take::<Bar>().unwrap();
1995 assert_eq!(y, Bar { x: 2 });
1996 }
1997
1998 #[test]
1999 fn not_dynamic_names() {
2000 let list = Vec::<usize>::new();
2001 let dyn_list = list.to_dynamic_list();
2002 assert_ne!(dyn_list.reflect_type_path(), Vec::<usize>::type_path());
2003
2004 let array = [b'0'; 4];
2005 let dyn_array = array.to_dynamic_array();
2006 assert_ne!(dyn_array.reflect_type_path(), <[u8; 4]>::type_path());
2007
2008 let map = HashMap::<usize, String>::default();
2009 let dyn_map = map.to_dynamic_map();
2010 assert_ne!(
2011 dyn_map.reflect_type_path(),
2012 HashMap::<usize, String>::type_path()
2013 );
2014
2015 let tuple = (0usize, "1".to_string(), 2.0f32);
2016 let mut dyn_tuple = tuple.to_dynamic_tuple();
2017 dyn_tuple.insert::<usize>(3);
2018 assert_ne!(
2019 dyn_tuple.reflect_type_path(),
2020 <(usize, String, f32, usize)>::type_path()
2021 );
2022
2023 #[derive(Reflect)]
2024 struct TestStruct {
2025 a: usize,
2026 }
2027 let struct_ = TestStruct { a: 0 };
2028 let dyn_struct = struct_.to_dynamic_struct();
2029 assert_ne!(dyn_struct.reflect_type_path(), TestStruct::type_path());
2030
2031 #[derive(Reflect)]
2032 struct TestTupleStruct(usize);
2033 let tuple_struct = TestTupleStruct(0);
2034 let dyn_tuple_struct = tuple_struct.to_dynamic_tuple_struct();
2035 assert_ne!(
2036 dyn_tuple_struct.reflect_type_path(),
2037 TestTupleStruct::type_path()
2038 );
2039 }
2040
2041 macro_rules! assert_type_paths {
2042 ($($ty:ty => $long:literal, $short:literal,)*) => {
2043 $(
2044 assert_eq!(<$ty as TypePath>::type_path(), $long);
2045 assert_eq!(<$ty as TypePath>::short_type_path(), $short);
2046 )*
2047 };
2048 }
2049
2050 #[test]
2051 fn reflect_type_path() {
2052 #[derive(TypePath)]
2053 struct Param;
2054
2055 #[derive(TypePath)]
2056 struct Derive;
2057
2058 #[derive(TypePath)]
2059 #[type_path = "my_alias"]
2060 struct DerivePath;
2061
2062 #[derive(TypePath)]
2063 #[type_path = "my_alias"]
2064 #[type_name = "MyDerivePathName"]
2065 struct DerivePathName;
2066
2067 #[derive(TypePath)]
2068 struct DeriveG<T>(PhantomData<T>);
2069
2070 #[derive(TypePath)]
2071 #[type_path = "my_alias"]
2072 struct DerivePathG<T, const N: usize>(PhantomData<T>);
2073
2074 #[derive(TypePath)]
2075 #[type_path = "my_alias"]
2076 #[type_name = "MyDerivePathNameG"]
2077 struct DerivePathNameG<T>(PhantomData<T>);
2078
2079 struct Macro;
2080 impl_type_path!((in my_alias) Macro);
2081
2082 struct MacroName;
2083 impl_type_path!((in my_alias as MyMacroName) MacroName);
2084
2085 struct MacroG<T, const N: usize>(PhantomData<T>);
2086 impl_type_path!((in my_alias) MacroG<T, const N: usize>);
2087
2088 struct MacroNameG<T>(PhantomData<T>);
2089 impl_type_path!((in my_alias as MyMacroNameG) MacroNameG<T>);
2090
2091 assert_type_paths! {
2092 Derive => "bevy_reflect::tests::Derive", "Derive",
2093 DerivePath => "my_alias::DerivePath", "DerivePath",
2094 DerivePathName => "my_alias::MyDerivePathName", "MyDerivePathName",
2095 DeriveG<Param> => "bevy_reflect::tests::DeriveG<bevy_reflect::tests::Param>", "DeriveG<Param>",
2096 DerivePathG<Param, 10> => "my_alias::DerivePathG<bevy_reflect::tests::Param, 10>", "DerivePathG<Param, 10>",
2097 DerivePathNameG<Param> => "my_alias::MyDerivePathNameG<bevy_reflect::tests::Param>", "MyDerivePathNameG<Param>",
2098 Macro => "my_alias::Macro", "Macro",
2099 MacroName => "my_alias::MyMacroName", "MyMacroName",
2100 MacroG<Param, 10> => "my_alias::MacroG<bevy_reflect::tests::Param, 10>", "MacroG<Param, 10>",
2101 MacroNameG<Param> => "my_alias::MyMacroNameG<bevy_reflect::tests::Param>", "MyMacroNameG<Param>",
2102 }
2103 }
2104
2105 #[test]
2106 fn std_type_paths() {
2107 #[derive(Clone)]
2108 struct Type;
2109
2110 impl TypePath for Type {
2111 fn type_path() -> &'static str {
2112 "Long"
2114 }
2115
2116 fn short_type_path() -> &'static str {
2117 "Short"
2118 }
2119 }
2120
2121 assert_type_paths! {
2122 u8 => "u8", "u8",
2123 Type => "Long", "Short",
2124 &Type => "&Long", "&Short",
2125 [Type] => "[Long]", "[Short]",
2126 &[Type] => "&[Long]", "&[Short]",
2127 [Type; 0] => "[Long; 0]", "[Short; 0]",
2128 [Type; 100] => "[Long; 100]", "[Short; 100]",
2129 () => "()", "()",
2130 (Type,) => "(Long,)", "(Short,)",
2131 (Type, Type) => "(Long, Long)", "(Short, Short)",
2132 (Type, Type, Type) => "(Long, Long, Long)", "(Short, Short, Short)",
2133 Cow<'static, Type> => "alloc::borrow::Cow<Long>", "Cow<Short>",
2134 }
2135 }
2136
2137 #[test]
2138 fn reflect_type_info() {
2139 let info = i32::type_info();
2141 assert_eq!(i32::type_path(), info.type_path());
2142 assert_eq!(TypeId::of::<i32>(), info.type_id());
2143
2144 assert_eq!(
2146 TypeId::of::<dyn Reflect>(),
2147 <dyn Reflect as Typed>::type_info().type_id()
2148 );
2149
2150 let value: &dyn Reflect = &123_i32;
2152 let info = value.reflect_type_info();
2153 assert!(info.is::<i32>());
2154
2155 #[derive(Reflect)]
2157 struct MyStruct {
2158 foo: i32,
2159 bar: usize,
2160 }
2161
2162 let info = MyStruct::type_info().as_struct().unwrap();
2163 assert!(info.is::<MyStruct>());
2164 assert_eq!(MyStruct::type_path(), info.type_path());
2165 assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2166 assert_eq!(TypeId::of::<i32>(), info.field("foo").unwrap().type_id());
2167 assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2168 assert!(info.field("foo").unwrap().is::<i32>());
2169 assert_eq!("foo", info.field("foo").unwrap().name());
2170 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2171
2172 let value: &dyn Reflect = &MyStruct { foo: 123, bar: 321 };
2173 let info = value.reflect_type_info();
2174 assert!(info.is::<MyStruct>());
2175
2176 #[derive(Reflect)]
2178 struct MyGenericStruct<T> {
2179 foo: T,
2180 bar: usize,
2181 }
2182
2183 let info = <MyGenericStruct<i32>>::type_info().as_struct().unwrap();
2184 assert!(info.is::<MyGenericStruct<i32>>());
2185 assert_eq!(MyGenericStruct::<i32>::type_path(), info.type_path());
2186 assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2187 assert_eq!("foo", info.field("foo").unwrap().name());
2188 assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2189 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2190
2191 let value: &dyn Reflect = &MyGenericStruct {
2192 foo: String::from("Hello!"),
2193 bar: 321,
2194 };
2195 let info = value.reflect_type_info();
2196 assert!(info.is::<MyGenericStruct<String>>());
2197
2198 #[derive(Reflect)]
2200 #[reflect(from_reflect = false)]
2201 struct MyDynamicStruct {
2202 foo: DynamicStruct,
2203 bar: usize,
2204 }
2205
2206 let info = MyDynamicStruct::type_info();
2207 if let TypeInfo::Struct(info) = info {
2208 assert!(info.is::<MyDynamicStruct>());
2209 assert_eq!(MyDynamicStruct::type_path(), info.type_path());
2210 assert_eq!(
2211 DynamicStruct::type_path(),
2212 info.field("foo").unwrap().type_path()
2213 );
2214 assert_eq!("foo", info.field("foo").unwrap().name());
2215 assert!(info.field("foo").unwrap().type_info().is_none());
2216 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2217 } else {
2218 panic!("Expected `TypeInfo::Struct`");
2219 }
2220
2221 let value: &dyn Reflect = &MyDynamicStruct {
2222 foo: DynamicStruct::default(),
2223 bar: 321,
2224 };
2225 let info = value.reflect_type_info();
2226 assert!(info.is::<MyDynamicStruct>());
2227
2228 #[derive(Reflect)]
2230 struct MyTupleStruct(usize, i32, MyStruct);
2231
2232 let info = MyTupleStruct::type_info().as_tuple_struct().unwrap();
2233
2234 assert!(info.is::<MyTupleStruct>());
2235 assert_eq!(MyTupleStruct::type_path(), info.type_path());
2236 assert_eq!(i32::type_path(), info.field_at(1).unwrap().type_path());
2237 assert!(info.field_at(1).unwrap().type_info().unwrap().is::<i32>());
2238 assert!(info.field_at(1).unwrap().is::<i32>());
2239
2240 type MyTuple = (u32, f32, String);
2242
2243 let info = MyTuple::type_info().as_tuple().unwrap();
2244
2245 assert!(info.is::<MyTuple>());
2246 assert_eq!(MyTuple::type_path(), info.type_path());
2247 assert_eq!(f32::type_path(), info.field_at(1).unwrap().type_path());
2248 assert!(info.field_at(1).unwrap().type_info().unwrap().is::<f32>());
2249
2250 let value: &dyn Reflect = &(123_u32, 1.23_f32, String::from("Hello!"));
2251 let info = value.reflect_type_info();
2252 assert!(info.is::<MyTuple>());
2253
2254 type MyList = Vec<usize>;
2256
2257 let info = MyList::type_info().as_list().unwrap();
2258
2259 assert!(info.is::<MyList>());
2260 assert!(info.item_ty().is::<usize>());
2261 assert!(info.item_info().unwrap().is::<usize>());
2262 assert_eq!(MyList::type_path(), info.type_path());
2263 assert_eq!(usize::type_path(), info.item_ty().path());
2264
2265 let value: &dyn Reflect = &vec![123_usize];
2266 let info = value.reflect_type_info();
2267 assert!(info.is::<MyList>());
2268
2269 #[cfg(feature = "smallvec")]
2271 {
2272 type MySmallVec = smallvec::SmallVec<[String; 2]>;
2273
2274 let info = MySmallVec::type_info().as_list().unwrap();
2275 assert!(info.is::<MySmallVec>());
2276 assert!(info.item_ty().is::<String>());
2277 assert!(info.item_info().unwrap().is::<String>());
2278 assert_eq!(MySmallVec::type_path(), info.type_path());
2279 assert_eq!(String::type_path(), info.item_ty().path());
2280
2281 let value: MySmallVec = smallvec::smallvec![String::default(); 2];
2282 let value: &dyn Reflect = &value;
2283 let info = value.reflect_type_info();
2284 assert!(info.is::<MySmallVec>());
2285 }
2286
2287 type MyArray = [usize; 3];
2289
2290 let info = MyArray::type_info().as_array().unwrap();
2291 assert!(info.is::<MyArray>());
2292 assert!(info.item_ty().is::<usize>());
2293 assert!(info.item_info().unwrap().is::<usize>());
2294 assert_eq!(MyArray::type_path(), info.type_path());
2295 assert_eq!(usize::type_path(), info.item_ty().path());
2296 assert_eq!(3, info.capacity());
2297
2298 let value: &dyn Reflect = &[1usize, 2usize, 3usize];
2299 let info = value.reflect_type_info();
2300 assert!(info.is::<MyArray>());
2301
2302 type MyCowStr = Cow<'static, str>;
2304
2305 let info = MyCowStr::type_info().as_opaque().unwrap();
2306
2307 assert!(info.is::<MyCowStr>());
2308 assert_eq!(core::any::type_name::<MyCowStr>(), info.type_path());
2309
2310 let value: &dyn Reflect = &Cow::<'static, str>::Owned("Hello!".to_string());
2311 let info = value.reflect_type_info();
2312 assert!(info.is::<MyCowStr>());
2313
2314 type MyCowSlice = Cow<'static, [u8]>;
2316
2317 let info = MyCowSlice::type_info().as_list().unwrap();
2318
2319 assert!(info.is::<MyCowSlice>());
2320 assert!(info.item_ty().is::<u8>());
2321 assert!(info.item_info().unwrap().is::<u8>());
2322 assert_eq!(core::any::type_name::<MyCowSlice>(), info.type_path());
2323 assert_eq!(core::any::type_name::<u8>(), info.item_ty().path());
2324
2325 let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]);
2326 let info = value.reflect_type_info();
2327 assert!(info.is::<MyCowSlice>());
2328
2329 type MyMap = HashMap<usize, f32>;
2331
2332 let info = MyMap::type_info().as_map().unwrap();
2333
2334 assert!(info.is::<MyMap>());
2335 assert!(info.key_ty().is::<usize>());
2336 assert!(info.value_ty().is::<f32>());
2337 assert!(info.key_info().unwrap().is::<usize>());
2338 assert!(info.value_info().unwrap().is::<f32>());
2339 assert_eq!(MyMap::type_path(), info.type_path());
2340 assert_eq!(usize::type_path(), info.key_ty().path());
2341 assert_eq!(f32::type_path(), info.value_ty().path());
2342
2343 let value: &dyn Reflect = &MyMap::default();
2344 let info = value.reflect_type_info();
2345 assert!(info.is::<MyMap>());
2346
2347 type MyValue = String;
2349
2350 let info = MyValue::type_info().as_opaque().unwrap();
2351
2352 assert!(info.is::<MyValue>());
2353 assert_eq!(MyValue::type_path(), info.type_path());
2354
2355 let value: &dyn Reflect = &String::from("Hello!");
2356 let info = value.reflect_type_info();
2357 assert!(info.is::<MyValue>());
2358 }
2359
2360 #[test]
2361 fn get_represented_kind_info() {
2362 #[derive(Reflect)]
2363 struct SomeStruct;
2364
2365 #[derive(Reflect)]
2366 struct SomeTupleStruct(f32);
2367
2368 #[derive(Reflect)]
2369 enum SomeEnum {
2370 Foo,
2371 Bar,
2372 }
2373
2374 let dyn_struct: &dyn Struct = &SomeStruct;
2375 let _: &StructInfo = dyn_struct.get_represented_struct_info().unwrap();
2376
2377 let dyn_map: &dyn Map = &HashMap::<(), ()>::default();
2378 let _: &MapInfo = dyn_map.get_represented_map_info().unwrap();
2379
2380 let dyn_array: &dyn Array = &[1, 2, 3];
2381 let _: &ArrayInfo = dyn_array.get_represented_array_info().unwrap();
2382
2383 let dyn_list: &dyn List = &vec![1, 2, 3];
2384 let _: &ListInfo = dyn_list.get_represented_list_info().unwrap();
2385
2386 let dyn_tuple_struct: &dyn TupleStruct = &SomeTupleStruct(5.0);
2387 let _: &TupleStructInfo = dyn_tuple_struct
2388 .get_represented_tuple_struct_info()
2389 .unwrap();
2390
2391 let dyn_enum: &dyn Enum = &SomeEnum::Foo;
2392 let _: &EnumInfo = dyn_enum.get_represented_enum_info().unwrap();
2393 }
2394
2395 #[test]
2396 fn should_permit_higher_ranked_lifetimes() {
2397 #[derive(Reflect)]
2398 #[reflect(from_reflect = false)]
2399 struct TestStruct {
2400 #[reflect(ignore)]
2401 _hrl: for<'a> fn(&'a str) -> &'a str,
2402 }
2403
2404 impl Default for TestStruct {
2405 fn default() -> Self {
2406 TestStruct {
2407 _hrl: |input| input,
2408 }
2409 }
2410 }
2411
2412 fn get_type_registration<T: GetTypeRegistration>() {}
2413 get_type_registration::<TestStruct>();
2414 }
2415
2416 #[test]
2417 fn should_permit_valid_represented_type_for_dynamic() {
2418 let type_info = <[i32; 2] as Typed>::type_info();
2419 let mut dynamic_array = [123; 2].to_dynamic_array();
2420 dynamic_array.set_represented_type(Some(type_info));
2421 }
2422
2423 #[test]
2424 #[should_panic(expected = "expected TypeInfo::Array but received")]
2425 fn should_prohibit_invalid_represented_type_for_dynamic() {
2426 let type_info = <(i32, i32) as Typed>::type_info();
2427 let mut dynamic_array = [123; 2].to_dynamic_array();
2428 dynamic_array.set_represented_type(Some(type_info));
2429 }
2430
2431 #[cfg(feature = "documentation")]
2432 mod docstrings {
2433 use super::*;
2434
2435 #[test]
2436 fn should_not_contain_docs() {
2437 #[derive(Reflect)]
2440 struct SomeStruct;
2441
2442 let info = <SomeStruct as Typed>::type_info();
2443 assert_eq!(None, info.docs());
2444
2445 #[derive(Reflect)]
2448 struct SomeOtherStruct;
2449
2450 let info = <SomeOtherStruct as Typed>::type_info();
2451 assert_eq!(None, info.docs());
2452 }
2453
2454 #[test]
2455 fn should_contain_docs() {
2456 #[derive(Reflect)]
2464 struct SomeStruct;
2465
2466 let info = <SomeStruct as Typed>::type_info();
2467 assert_eq!(
2468 Some(" Some struct.\n\n # Example\n\n ```ignore (This is only used for a unit test, no need to doc test)\n let some_struct = SomeStruct;\n ```"),
2469 info.docs()
2470 );
2471
2472 #[doc = "The compiler automatically converts `///`-style comments into `#[doc]` attributes."]
2473 #[doc = "Of course, you _could_ use the attribute directly if you wanted to."]
2474 #[doc = "Both will be reflected."]
2475 #[derive(Reflect)]
2476 struct SomeOtherStruct;
2477
2478 let info = <SomeOtherStruct as Typed>::type_info();
2479 assert_eq!(
2480 Some("The compiler automatically converts `///`-style comments into `#[doc]` attributes.\nOf course, you _could_ use the attribute directly if you wanted to.\nBoth will be reflected."),
2481 info.docs()
2482 );
2483
2484 #[derive(Reflect)]
2486 struct SomeTupleStruct(usize);
2487
2488 let info = <SomeTupleStruct as Typed>::type_info();
2489 assert_eq!(Some(" Some tuple struct."), info.docs());
2490
2491 #[derive(Reflect)]
2493 enum SomeEnum {
2494 Foo,
2495 }
2496
2497 let info = <SomeEnum as Typed>::type_info();
2498 assert_eq!(Some(" Some enum."), info.docs());
2499
2500 #[derive(Clone)]
2501 struct SomePrimitive;
2502 impl_reflect_opaque!(
2503 (in bevy_reflect::tests) SomePrimitive
2505 );
2506
2507 let info = <SomePrimitive as Typed>::type_info();
2508 assert_eq!(
2509 Some(" Some primitive for which we have attributed custom documentation."),
2510 info.docs()
2511 );
2512 }
2513
2514 #[test]
2515 fn fields_should_contain_docs() {
2516 #[derive(Reflect)]
2517 struct SomeStruct {
2518 name: String,
2520 index: usize,
2522 data: Vec<i32>,
2524 }
2525
2526 let info = <SomeStruct as Typed>::type_info().as_struct().unwrap();
2527
2528 let mut fields = info.iter();
2529 assert_eq!(Some(" The name"), fields.next().unwrap().docs());
2530 assert_eq!(Some(" The index"), fields.next().unwrap().docs());
2531 assert_eq!(None, fields.next().unwrap().docs());
2532 }
2533
2534 #[test]
2535 fn variants_should_contain_docs() {
2536 #[derive(Reflect)]
2537 enum SomeEnum {
2538 Nothing,
2540 A(
2542 usize,
2544 ),
2545 B {
2547 name: String,
2549 },
2550 }
2551
2552 let info = <SomeEnum as Typed>::type_info().as_enum().unwrap();
2553
2554 let mut variants = info.iter();
2555 assert_eq!(None, variants.next().unwrap().docs());
2556
2557 let variant = variants.next().unwrap().as_tuple_variant().unwrap();
2558 assert_eq!(Some(" Option A"), variant.docs());
2559 let field = variant.field_at(0).unwrap();
2560 assert_eq!(Some(" Index"), field.docs());
2561
2562 let variant = variants.next().unwrap().as_struct_variant().unwrap();
2563 assert_eq!(Some(" Option B"), variant.docs());
2564 let field = variant.field_at(0).unwrap();
2565 assert_eq!(Some(" Name"), field.docs());
2566 }
2567 }
2568
2569 #[test]
2570 fn into_reflect() {
2571 trait TestTrait: Reflect {}
2572
2573 #[derive(Reflect)]
2574 struct TestStruct;
2575
2576 impl TestTrait for TestStruct {}
2577
2578 let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
2579
2580 let _ = trait_object.into_reflect();
2582 }
2583
2584 #[test]
2585 fn as_reflect() {
2586 trait TestTrait: Reflect {}
2587
2588 #[derive(Reflect)]
2589 struct TestStruct;
2590
2591 impl TestTrait for TestStruct {}
2592
2593 let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
2594
2595 let _ = trait_object.as_reflect();
2597 }
2598
2599 #[test]
2600 fn should_reflect_debug() {
2601 #[derive(Reflect)]
2602 struct Test {
2603 value: usize,
2604 list: Vec<String>,
2605 array: [f32; 3],
2606 map: HashMap<i32, f32>,
2607 a_struct: SomeStruct,
2608 a_tuple_struct: SomeTupleStruct,
2609 enum_unit: SomeEnum,
2610 enum_tuple: SomeEnum,
2611 enum_struct: SomeEnum,
2612 custom: CustomDebug,
2613 #[reflect(ignore)]
2614 #[expect(dead_code, reason = "This value is intended to not be reflected.")]
2615 ignored: isize,
2616 }
2617
2618 #[derive(Reflect)]
2619 struct SomeStruct {
2620 foo: String,
2621 }
2622
2623 #[derive(Reflect)]
2624 enum SomeEnum {
2625 A,
2626 B(usize),
2627 C { value: i32 },
2628 }
2629
2630 #[derive(Reflect)]
2631 struct SomeTupleStruct(String);
2632
2633 #[derive(Reflect)]
2634 #[reflect(Debug)]
2635 struct CustomDebug;
2636 impl Debug for CustomDebug {
2637 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
2638 f.write_str("Cool debug!")
2639 }
2640 }
2641
2642 let mut map = <HashMap<_, _>>::default();
2643 map.insert(123, 1.23);
2644
2645 let test = Test {
2646 value: 123,
2647 list: vec![String::from("A"), String::from("B"), String::from("C")],
2648 array: [1.0, 2.0, 3.0],
2649 map,
2650 a_struct: SomeStruct {
2651 foo: String::from("A Struct!"),
2652 },
2653 a_tuple_struct: SomeTupleStruct(String::from("A Tuple Struct!")),
2654 enum_unit: SomeEnum::A,
2655 enum_tuple: SomeEnum::B(123),
2656 enum_struct: SomeEnum::C { value: 321 },
2657 custom: CustomDebug,
2658 ignored: 321,
2659 };
2660
2661 let reflected: &dyn Reflect = &test;
2662 let expected = r#"
2663bevy_reflect::tests::Test {
2664 value: 123,
2665 list: [
2666 "A",
2667 "B",
2668 "C",
2669 ],
2670 array: [
2671 1.0,
2672 2.0,
2673 3.0,
2674 ],
2675 map: {
2676 123: 1.23,
2677 },
2678 a_struct: bevy_reflect::tests::SomeStruct {
2679 foo: "A Struct!",
2680 },
2681 a_tuple_struct: bevy_reflect::tests::SomeTupleStruct(
2682 "A Tuple Struct!",
2683 ),
2684 enum_unit: A,
2685 enum_tuple: B(
2686 123,
2687 ),
2688 enum_struct: C {
2689 value: 321,
2690 },
2691 custom: Cool debug!,
2692}"#;
2693
2694 assert_eq!(expected, format!("\n{reflected:#?}"));
2695 }
2696
2697 #[test]
2698 fn multiple_reflect_lists() {
2699 #[derive(Hash, PartialEq, Reflect)]
2700 #[reflect(Debug, Hash)]
2701 #[reflect(PartialEq)]
2702 struct Foo(i32);
2703
2704 impl Debug for Foo {
2705 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
2706 write!(f, "Foo")
2707 }
2708 }
2709
2710 let foo = Foo(123);
2711 let foo: &dyn PartialReflect = &foo;
2712
2713 assert!(foo.reflect_hash().is_some());
2714 assert_eq!(Some(true), foo.reflect_partial_eq(foo));
2715 assert_eq!("Foo".to_string(), format!("{foo:?}"));
2716 }
2717
2718 #[test]
2719 fn custom_debug_function() {
2720 #[derive(Reflect)]
2721 #[reflect(Debug(custom_debug))]
2722 struct Foo {
2723 a: u32,
2724 }
2725
2726 fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> core::fmt::Result {
2727 write!(f, "123")
2728 }
2729
2730 let foo = Foo { a: 1 };
2731 let foo: &dyn Reflect = &foo;
2732
2733 assert_eq!("123", format!("{foo:?}"));
2734 }
2735
2736 #[test]
2737 fn should_allow_custom_where() {
2738 #[derive(Reflect)]
2739 #[reflect(where T: Default)]
2740 struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2741
2742 #[derive(Default, TypePath)]
2743 struct Bar;
2744
2745 #[derive(TypePath)]
2746 struct Baz;
2747
2748 assert_impl_all!(Foo<Bar>: Reflect);
2749 assert_not_impl_all!(Foo<Baz>: Reflect);
2750 }
2751
2752 #[test]
2753 fn should_allow_empty_custom_where() {
2754 #[derive(Reflect)]
2755 #[reflect(where)]
2756 struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2757
2758 #[derive(TypePath)]
2759 struct Bar;
2760
2761 assert_impl_all!(Foo<Bar>: Reflect);
2762 }
2763
2764 #[test]
2765 fn should_allow_multiple_custom_where() {
2766 #[derive(Reflect)]
2767 #[reflect(where T: Default)]
2768 #[reflect(where U: core::ops::Add<T>)]
2769 struct Foo<T, U>(T, U);
2770
2771 #[allow(
2772 clippy::allow_attributes,
2773 dead_code,
2774 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
2775 )]
2776 #[derive(Reflect)]
2777 struct Baz {
2778 a: Foo<i32, i32>,
2779 b: Foo<u32, u32>,
2780 }
2781
2782 assert_impl_all!(Foo<i32, i32>: Reflect);
2783 assert_not_impl_all!(Foo<i32, usize>: Reflect);
2784 }
2785
2786 #[test]
2787 fn should_allow_custom_where_with_assoc_type() {
2788 trait Trait {
2789 type Assoc;
2790 }
2791
2792 #[derive(Reflect)]
2794 #[reflect(where T::Assoc: core::fmt::Display)]
2795 struct Foo<T: Trait>(T::Assoc);
2796
2797 #[derive(TypePath)]
2798 struct Bar;
2799
2800 impl Trait for Bar {
2801 type Assoc = usize;
2802 }
2803
2804 #[derive(TypePath)]
2805 struct Baz;
2806
2807 impl Trait for Baz {
2808 type Assoc = (f32, f32);
2809 }
2810
2811 assert_impl_all!(Foo<Bar>: Reflect);
2812 assert_not_impl_all!(Foo<Baz>: Reflect);
2813 }
2814
2815 #[test]
2816 fn should_allow_empty_enums() {
2817 #[derive(Reflect)]
2818 enum Empty {}
2819
2820 assert_impl_all!(Empty: Reflect);
2821 }
2822
2823 #[test]
2824 fn recursive_typed_storage_does_not_hang() {
2825 #[derive(Reflect)]
2826 struct Recurse<T>(T);
2827
2828 let _ = <Recurse<Recurse<()>> as Typed>::type_info();
2829 let _ = <Recurse<Recurse<()>> as TypePath>::type_path();
2830
2831 #[derive(Reflect)]
2832 #[reflect(no_field_bounds)]
2833 struct SelfRecurse {
2834 recurse: Vec<SelfRecurse>,
2835 }
2836
2837 let _ = <SelfRecurse as Typed>::type_info();
2838 let _ = <SelfRecurse as TypePath>::type_path();
2839
2840 #[derive(Reflect)]
2841 #[reflect(no_field_bounds)]
2842 enum RecurseA {
2843 Recurse(RecurseB),
2844 }
2845
2846 #[derive(Reflect)]
2847 struct RecurseB {
2849 vector: Vec<RecurseA>,
2850 }
2851
2852 let _ = <RecurseA as Typed>::type_info();
2853 let _ = <RecurseA as TypePath>::type_path();
2854 let _ = <RecurseB as Typed>::type_info();
2855 let _ = <RecurseB as TypePath>::type_path();
2856 }
2857
2858 #[test]
2859 fn recursive_registration_does_not_hang() {
2860 #[derive(Reflect)]
2861 struct Recurse<T>(T);
2862
2863 let mut registry = TypeRegistry::empty();
2864
2865 registry.register::<Recurse<Recurse<()>>>();
2866
2867 #[derive(Reflect)]
2868 #[reflect(no_field_bounds)]
2869 struct SelfRecurse {
2870 recurse: Vec<SelfRecurse>,
2871 }
2872
2873 registry.register::<SelfRecurse>();
2874
2875 #[derive(Reflect)]
2876 #[reflect(no_field_bounds)]
2877 enum RecurseA {
2878 Recurse(RecurseB),
2879 }
2880
2881 #[derive(Reflect)]
2882 struct RecurseB {
2883 vector: Vec<RecurseA>,
2884 }
2885
2886 registry.register::<RecurseA>();
2887 assert!(registry.contains(TypeId::of::<RecurseA>()));
2888 assert!(registry.contains(TypeId::of::<RecurseB>()));
2889 }
2890
2891 #[test]
2892 fn can_opt_out_type_path() {
2893 #[derive(Reflect)]
2894 #[reflect(type_path = false)]
2895 struct Foo<T> {
2896 #[reflect(ignore)]
2897 _marker: PhantomData<T>,
2898 }
2899
2900 struct NotTypePath;
2901
2902 impl<T: 'static> TypePath for Foo<T> {
2903 fn type_path() -> &'static str {
2904 core::any::type_name::<Self>()
2905 }
2906
2907 fn short_type_path() -> &'static str {
2908 static CELL: GenericTypePathCell = GenericTypePathCell::new();
2909 CELL.get_or_insert::<Self, _>(|| ShortName::of::<Self>().to_string())
2910 }
2911
2912 fn type_ident() -> Option<&'static str> {
2913 Some("Foo")
2914 }
2915
2916 fn crate_name() -> Option<&'static str> {
2917 Some("bevy_reflect")
2918 }
2919
2920 fn module_path() -> Option<&'static str> {
2921 Some("bevy_reflect::tests")
2922 }
2923 }
2924
2925 let path = <Foo<NotTypePath> as TypePath>::type_path();
2927 assert_eq!("bevy_reflect::tests::can_opt_out_type_path::Foo<bevy_reflect::tests::can_opt_out_type_path::NotTypePath>", path);
2928
2929 let mut registry = TypeRegistry::default();
2931 registry.register::<Foo<NotTypePath>>();
2932
2933 let registration = registry.get(TypeId::of::<Foo<NotTypePath>>()).unwrap();
2934 assert_eq!(
2935 "Foo<NotTypePath>",
2936 registration.type_info().type_path_table().short_path()
2937 );
2938 }
2939
2940 #[test]
2941 fn dynamic_types_debug_format() {
2942 #[derive(Debug, Reflect)]
2943 struct TestTupleStruct(u32);
2944
2945 #[derive(Debug, Reflect)]
2946 enum TestEnum {
2947 A(u32),
2948 B,
2949 }
2950
2951 #[derive(Debug, Reflect)]
2952 struct TestStruct {
2954 tuple: (u32, u32),
2956 tuple_struct: TestTupleStruct,
2958 list: Vec<u32>,
2960 array: [u32; 3],
2962 e: TestEnum,
2964 map: HashMap<u32, u32>,
2966 value: u32,
2968 }
2969 let mut map = <HashMap<_, _>>::default();
2970 map.insert(9, 10);
2971 let mut test_struct: DynamicStruct = TestStruct {
2972 tuple: (0, 1),
2973 list: vec![2, 3, 4],
2974 array: [5, 6, 7],
2975 tuple_struct: TestTupleStruct(8),
2976 e: TestEnum::A(11),
2977 map,
2978 value: 12,
2979 }
2980 .to_dynamic_struct();
2981
2982 let mut test_unknown_struct = DynamicStruct::default();
2984 test_unknown_struct.insert("a", 13);
2985 test_struct.insert("unknown_struct", test_unknown_struct);
2986 let mut test_unknown_tuple_struct = DynamicTupleStruct::default();
2988 test_unknown_tuple_struct.insert(14);
2989 test_struct.insert("unknown_tuplestruct", test_unknown_tuple_struct);
2990 assert_eq!(
2991 format!("{test_struct:?}"),
2992 "DynamicStruct(bevy_reflect::tests::TestStruct { \
2993 tuple: DynamicTuple((0, 1)), \
2994 tuple_struct: DynamicTupleStruct(bevy_reflect::tests::TestTupleStruct(8)), \
2995 list: DynamicList([2, 3, 4]), \
2996 array: DynamicArray([5, 6, 7]), \
2997 e: DynamicEnum(A(11)), \
2998 map: DynamicMap({9: 10}), \
2999 value: 12, \
3000 unknown_struct: DynamicStruct(_ { a: 13 }), \
3001 unknown_tuplestruct: DynamicTupleStruct(_(14)) \
3002 })"
3003 );
3004 }
3005
3006 #[test]
3007 fn assert_impl_reflect_macro_on_all() {
3008 struct Struct {
3009 foo: (),
3010 }
3011 struct TupleStruct(());
3012 enum Enum {
3013 Foo { foo: () },
3014 Bar(()),
3015 }
3016
3017 impl_reflect!(
3018 #[type_path = "my_crate::foo"]
3019 struct Struct {
3020 foo: (),
3021 }
3022 );
3023
3024 impl_reflect!(
3025 #[type_path = "my_crate::foo"]
3026 struct TupleStruct(());
3027 );
3028
3029 impl_reflect!(
3030 #[type_path = "my_crate::foo"]
3031 enum Enum {
3032 Foo { foo: () },
3033 Bar(()),
3034 }
3035 );
3036
3037 assert_impl_all!(Struct: Reflect);
3038 assert_impl_all!(TupleStruct: Reflect);
3039 assert_impl_all!(Enum: Reflect);
3040 }
3041
3042 #[test]
3043 fn should_reflect_remote_type() {
3044 mod external_crate {
3045 use alloc::string::String;
3046
3047 #[derive(Debug, Default)]
3048 pub struct TheirType {
3049 pub value: String,
3050 }
3051 }
3052
3053 #[reflect_remote(external_crate::TheirType)]
3055 #[derive(Debug, Default)]
3056 #[reflect(Debug, Default)]
3057 struct MyType {
3058 pub value: String,
3059 }
3060
3061 let mut patch = DynamicStruct::default();
3062 patch.set_represented_type(Some(MyType::type_info()));
3063 patch.insert("value", "Goodbye".to_string());
3064
3065 let mut data = MyType(external_crate::TheirType {
3066 value: "Hello".to_string(),
3067 });
3068
3069 assert_eq!("Hello", data.0.value);
3070 data.apply(&patch);
3071 assert_eq!("Goodbye", data.0.value);
3072
3073 #[derive(Reflect, Debug)]
3075 #[reflect(from_reflect = false)]
3076 struct ContainerStruct {
3077 #[reflect(remote = MyType)]
3078 their_type: external_crate::TheirType,
3079 }
3080
3081 let mut patch = DynamicStruct::default();
3082 patch.set_represented_type(Some(ContainerStruct::type_info()));
3083 patch.insert(
3084 "their_type",
3085 MyType(external_crate::TheirType {
3086 value: "Goodbye".to_string(),
3087 }),
3088 );
3089
3090 let mut data = ContainerStruct {
3091 their_type: external_crate::TheirType {
3092 value: "Hello".to_string(),
3093 },
3094 };
3095
3096 assert_eq!("Hello", data.their_type.value);
3097 data.apply(&patch);
3098 assert_eq!("Goodbye", data.their_type.value);
3099
3100 #[derive(Reflect, Debug)]
3102 struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3103
3104 let mut patch = DynamicTupleStruct::default();
3105 patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3106 patch.insert(MyType(external_crate::TheirType {
3107 value: "Goodbye".to_string(),
3108 }));
3109
3110 let mut data = ContainerTupleStruct(external_crate::TheirType {
3111 value: "Hello".to_string(),
3112 });
3113
3114 assert_eq!("Hello", data.0.value);
3115 data.apply(&patch);
3116 assert_eq!("Goodbye", data.0.value);
3117 }
3118
3119 #[test]
3120 fn should_reflect_remote_value_type() {
3121 mod external_crate {
3122 use alloc::string::String;
3123
3124 #[derive(Clone, Debug, Default)]
3125 pub struct TheirType {
3126 pub value: String,
3127 }
3128 }
3129
3130 #[reflect_remote(external_crate::TheirType)]
3132 #[derive(Clone, Debug, Default)]
3133 #[reflect(opaque)]
3134 #[reflect(Debug, Default)]
3135 struct MyType {
3136 pub value: String,
3137 }
3138
3139 let mut data = MyType(external_crate::TheirType {
3140 value: "Hello".to_string(),
3141 });
3142
3143 let patch = MyType(external_crate::TheirType {
3144 value: "Goodbye".to_string(),
3145 });
3146
3147 assert_eq!("Hello", data.0.value);
3148 data.apply(&patch);
3149 assert_eq!("Goodbye", data.0.value);
3150
3151 #[derive(Reflect, Debug)]
3153 #[reflect(from_reflect = false)]
3154 struct ContainerStruct {
3155 #[reflect(remote = MyType)]
3156 their_type: external_crate::TheirType,
3157 }
3158
3159 let mut patch = DynamicStruct::default();
3160 patch.set_represented_type(Some(ContainerStruct::type_info()));
3161 patch.insert(
3162 "their_type",
3163 MyType(external_crate::TheirType {
3164 value: "Goodbye".to_string(),
3165 }),
3166 );
3167
3168 let mut data = ContainerStruct {
3169 their_type: external_crate::TheirType {
3170 value: "Hello".to_string(),
3171 },
3172 };
3173
3174 assert_eq!("Hello", data.their_type.value);
3175 data.apply(&patch);
3176 assert_eq!("Goodbye", data.their_type.value);
3177
3178 #[derive(Reflect, Debug)]
3180 struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3181
3182 let mut patch = DynamicTupleStruct::default();
3183 patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3184 patch.insert(MyType(external_crate::TheirType {
3185 value: "Goodbye".to_string(),
3186 }));
3187
3188 let mut data = ContainerTupleStruct(external_crate::TheirType {
3189 value: "Hello".to_string(),
3190 });
3191
3192 assert_eq!("Hello", data.0.value);
3193 data.apply(&patch);
3194 assert_eq!("Goodbye", data.0.value);
3195 }
3196
3197 #[test]
3198 fn should_reflect_remote_type_from_module() {
3199 mod wrapper {
3200 use super::*;
3201
3202 pub mod external_crate {
3207 use alloc::string::String;
3208
3209 #[allow(
3210 clippy::allow_attributes,
3211 dead_code,
3212 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3213 )]
3214 pub struct TheirType {
3215 pub value: String,
3216 }
3217 }
3218
3219 #[reflect_remote(external_crate::TheirType)]
3220 pub struct MyType {
3221 pub value: String,
3222 }
3223 }
3224
3225 #[allow(
3226 clippy::allow_attributes,
3227 dead_code,
3228 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3229 )]
3230 #[derive(Reflect)]
3231 struct ContainerStruct {
3232 #[reflect(remote = wrapper::MyType)]
3233 their_type: wrapper::external_crate::TheirType,
3234 }
3235 }
3236
3237 #[test]
3238 fn should_reflect_remote_enum() {
3239 mod external_crate {
3240 use alloc::string::String;
3241
3242 #[derive(Debug, PartialEq, Eq)]
3243 pub enum TheirType {
3244 Unit,
3245 Tuple(usize),
3246 Struct { value: String },
3247 }
3248 }
3249
3250 #[reflect_remote(external_crate::TheirType)]
3252 #[derive(Debug)]
3253 #[reflect(Debug)]
3254 enum MyType {
3255 Unit,
3256 Tuple(usize),
3257 Struct { value: String },
3258 }
3259
3260 let mut patch = DynamicEnum::from(MyType(external_crate::TheirType::Tuple(123)));
3261
3262 let mut data = MyType(external_crate::TheirType::Unit);
3263
3264 assert_eq!(external_crate::TheirType::Unit, data.0);
3265 data.apply(&patch);
3266 assert_eq!(external_crate::TheirType::Tuple(123), data.0);
3267
3268 patch = DynamicEnum::from(MyType(external_crate::TheirType::Struct {
3269 value: "Hello world!".to_string(),
3270 }));
3271
3272 data.apply(&patch);
3273 assert_eq!(
3274 external_crate::TheirType::Struct {
3275 value: "Hello world!".to_string()
3276 },
3277 data.0
3278 );
3279
3280 #[derive(Reflect, Debug, PartialEq)]
3282 enum ContainerEnum {
3283 Foo,
3284 Bar {
3285 #[reflect(remote = MyType)]
3286 their_type: external_crate::TheirType,
3287 },
3288 }
3289
3290 let patch = DynamicEnum::from(ContainerEnum::Bar {
3291 their_type: external_crate::TheirType::Tuple(123),
3292 });
3293
3294 let mut data = ContainerEnum::Foo;
3295
3296 assert_eq!(ContainerEnum::Foo, data);
3297 data.apply(&patch);
3298 assert_eq!(
3299 ContainerEnum::Bar {
3300 their_type: external_crate::TheirType::Tuple(123)
3301 },
3302 data
3303 );
3304 }
3305
3306 #[test]
3307 fn should_reflect_nested_remote_type() {
3308 mod external_crate {
3309 pub struct TheirOuter<T> {
3310 pub a: TheirInner<T>,
3311 pub b: TheirInner<bool>,
3312 }
3313
3314 pub struct TheirInner<T>(pub T);
3315 }
3316
3317 #[reflect_remote(external_crate::TheirOuter<T>)]
3318 struct MyOuter<T: FromReflect + Reflectable> {
3319 #[reflect(remote = MyInner<T>)]
3320 pub a: external_crate::TheirInner<T>,
3321 #[reflect(remote = MyInner<bool>)]
3322 pub b: external_crate::TheirInner<bool>,
3323 }
3324
3325 #[reflect_remote(external_crate::TheirInner<T>)]
3326 struct MyInner<T: FromReflect>(pub T);
3327
3328 let mut patch = DynamicStruct::default();
3329 patch.set_represented_type(Some(MyOuter::<i32>::type_info()));
3330 patch.insert("a", MyInner(external_crate::TheirInner(321_i32)));
3331 patch.insert("b", MyInner(external_crate::TheirInner(true)));
3332
3333 let mut data = MyOuter(external_crate::TheirOuter {
3334 a: external_crate::TheirInner(123_i32),
3335 b: external_crate::TheirInner(false),
3336 });
3337
3338 assert_eq!(123, data.0.a.0);
3339 assert!(!data.0.b.0);
3340 data.apply(&patch);
3341 assert_eq!(321, data.0.a.0);
3342 assert!(data.0.b.0);
3343 }
3344
3345 #[test]
3346 fn should_reflect_nested_remote_enum() {
3347 mod external_crate {
3348 use core::fmt::Debug;
3349
3350 #[derive(Debug)]
3351 pub enum TheirOuter<T: Debug> {
3352 Unit,
3353 Tuple(TheirInner<T>),
3354 Struct { value: TheirInner<T> },
3355 }
3356 #[derive(Debug)]
3357 pub enum TheirInner<T: Debug> {
3358 Unit,
3359 Tuple(T),
3360 Struct { value: T },
3361 }
3362 }
3363
3364 #[reflect_remote(external_crate::TheirOuter<T>)]
3365 #[derive(Debug)]
3366 enum MyOuter<T: FromReflect + Reflectable + Debug> {
3367 Unit,
3368 Tuple(#[reflect(remote = MyInner<T>)] external_crate::TheirInner<T>),
3369 Struct {
3370 #[reflect(remote = MyInner<T>)]
3371 value: external_crate::TheirInner<T>,
3372 },
3373 }
3374
3375 #[reflect_remote(external_crate::TheirInner<T>)]
3376 #[derive(Debug)]
3377 enum MyInner<T: FromReflect + Debug> {
3378 Unit,
3379 Tuple(T),
3380 Struct { value: T },
3381 }
3382
3383 let mut patch = DynamicEnum::default();
3384 let mut value = DynamicStruct::default();
3385 value.insert("value", MyInner(external_crate::TheirInner::Tuple(123)));
3386 patch.set_variant("Struct", value);
3387
3388 let mut data = MyOuter(external_crate::TheirOuter::<i32>::Unit);
3389
3390 assert!(matches!(
3391 data,
3392 MyOuter(external_crate::TheirOuter::<i32>::Unit)
3393 ));
3394 data.apply(&patch);
3395 assert!(matches!(
3396 data,
3397 MyOuter(external_crate::TheirOuter::Struct {
3398 value: external_crate::TheirInner::Tuple(123)
3399 })
3400 ));
3401 }
3402
3403 #[test]
3404 fn should_take_remote_type() {
3405 mod external_crate {
3406 use alloc::string::String;
3407
3408 #[derive(Debug, Default, PartialEq, Eq)]
3409 pub struct TheirType {
3410 pub value: String,
3411 }
3412 }
3413
3414 #[reflect_remote(external_crate::TheirType)]
3416 #[derive(Debug, Default)]
3417 #[reflect(Debug, Default)]
3418 struct MyType {
3419 pub value: String,
3420 }
3421
3422 let input: Box<dyn Reflect> = Box::new(MyType(external_crate::TheirType {
3423 value: "Hello".to_string(),
3424 }));
3425
3426 let output: external_crate::TheirType = input
3427 .take()
3428 .expect("should downcast to `external_crate::TheirType`");
3429 assert_eq!(
3430 external_crate::TheirType {
3431 value: "Hello".to_string(),
3432 },
3433 output
3434 );
3435 }
3436
3437 #[test]
3438 fn should_try_take_remote_type() {
3439 mod external_crate {
3440 use alloc::string::String;
3441
3442 #[derive(Debug, Default, PartialEq, Eq)]
3443 pub struct TheirType {
3444 pub value: String,
3445 }
3446 }
3447
3448 #[reflect_remote(external_crate::TheirType)]
3450 #[derive(Debug, Default)]
3451 #[reflect(Debug, Default)]
3452 struct MyType {
3453 pub value: String,
3454 }
3455
3456 let input: Box<dyn PartialReflect> = Box::new(MyType(external_crate::TheirType {
3457 value: "Hello".to_string(),
3458 }));
3459
3460 let output: external_crate::TheirType = input
3461 .try_take()
3462 .expect("should downcast to `external_crate::TheirType`");
3463 assert_eq!(
3464 external_crate::TheirType {
3465 value: "Hello".to_string(),
3466 },
3467 output,
3468 );
3469 }
3470
3471 #[test]
3472 fn should_take_nested_remote_type() {
3473 mod external_crate {
3474 #[derive(PartialEq, Eq, Debug)]
3475 pub struct TheirOuter<T> {
3476 pub inner: TheirInner<T>,
3477 }
3478 #[derive(PartialEq, Eq, Debug)]
3479 pub struct TheirInner<T>(pub T);
3480 }
3481
3482 #[reflect_remote(external_crate::TheirOuter<T>)]
3483 struct MyOuter<T: FromReflect + Reflectable> {
3484 #[reflect(remote = MyInner<T>)]
3485 pub inner: external_crate::TheirInner<T>,
3486 }
3487
3488 #[reflect_remote(external_crate::TheirInner<T>)]
3489 struct MyInner<T: FromReflect>(pub T);
3490
3491 let input: Box<dyn Reflect> = Box::new(MyOuter(external_crate::TheirOuter {
3492 inner: external_crate::TheirInner(123),
3493 }));
3494
3495 let output: external_crate::TheirOuter<i32> = input
3496 .take()
3497 .expect("should downcast to `external_crate::TheirOuter`");
3498 assert_eq!(
3499 external_crate::TheirOuter {
3500 inner: external_crate::TheirInner(123),
3501 },
3502 output
3503 );
3504 }
3505
3506 #[test]
3508 fn should_serialize_opaque_remote_type() {
3509 mod external_crate {
3510 use serde::{Deserialize, Serialize};
3511 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
3512 pub struct Vector2<T>(pub [T; 2]);
3513 }
3514
3515 #[reflect_remote(external_crate::Vector2<i32>)]
3516 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
3517 #[reflect(Serialize, Deserialize)]
3518 #[reflect(opaque)]
3519 struct Vector2Wrapper([i32; 2]);
3520
3521 #[derive(Reflect, Debug, PartialEq)]
3522 struct Point(#[reflect(remote = Vector2Wrapper)] external_crate::Vector2<i32>);
3523
3524 let point = Point(external_crate::Vector2([1, 2]));
3525
3526 let mut registry = TypeRegistry::new();
3527 registry.register::<Point>();
3528 registry.register::<Vector2Wrapper>();
3529
3530 let serializer = ReflectSerializer::new(&point, ®istry);
3531 let serialized = ron::to_string(&serializer).unwrap();
3532 assert_eq!(serialized, r#"{"bevy_reflect::tests::Point":((((1,2))))}"#);
3533
3534 let mut deserializer = Deserializer::from_str(&serialized).unwrap();
3535 let reflect_deserializer = ReflectDeserializer::new(®istry);
3536 let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
3537 let point = <Point as FromReflect>::from_reflect(&*deserialized).unwrap();
3538 assert_eq!(point, Point(external_crate::Vector2([1, 2])));
3539 }
3540
3541 #[cfg(feature = "auto_register")]
3542 mod auto_register_reflect {
3543 use super::*;
3544
3545 #[test]
3546 fn should_ignore_auto_reflect_registration() {
3547 #[derive(Reflect)]
3548 #[reflect(no_auto_register)]
3549 struct NoAutomaticStruct {
3550 a: usize,
3551 }
3552
3553 let mut registry = TypeRegistry::default();
3554 registry.register_derived_types();
3555
3556 assert!(!registry.contains(TypeId::of::<NoAutomaticStruct>()));
3557 }
3558
3559 #[test]
3560 fn should_auto_register_reflect_for_all_supported_types() {
3561 #[derive(Reflect)]
3563 struct StructReflect {
3564 a: usize,
3565 }
3566
3567 #[derive(Reflect)]
3569 struct ZSTStructReflect;
3570
3571 #[derive(Reflect)]
3573 struct TupleStructReflect(pub u32);
3574
3575 #[derive(Reflect)]
3577 enum EnumReflect {
3578 A,
3579 B,
3580 }
3581
3582 #[derive(Reflect)]
3584 enum ZSTEnumReflect {}
3585
3586 #[derive(Reflect, Clone)]
3588 #[reflect(opaque)]
3589 struct OpaqueStructReflect {
3590 _a: usize,
3591 }
3592
3593 #[derive(Reflect, Clone)]
3595 #[reflect(opaque)]
3596 struct ZSTOpaqueStructReflect;
3597
3598 let mut registry = TypeRegistry::default();
3599 registry.register_derived_types();
3600
3601 assert!(registry.contains(TypeId::of::<StructReflect>()));
3602 assert!(registry.contains(TypeId::of::<ZSTStructReflect>()));
3603 assert!(registry.contains(TypeId::of::<TupleStructReflect>()));
3604 assert!(registry.contains(TypeId::of::<EnumReflect>()));
3605 assert!(registry.contains(TypeId::of::<ZSTEnumReflect>()));
3606 assert!(registry.contains(TypeId::of::<OpaqueStructReflect>()));
3607 assert!(registry.contains(TypeId::of::<ZSTOpaqueStructReflect>()));
3608 }
3609 }
3610
3611 #[cfg(feature = "glam")]
3612 mod glam {
3613 use super::*;
3614 use ::glam::{quat, vec3, Quat, Vec3};
3615
3616 #[test]
3617 fn quat_serialization() {
3618 let q = quat(1.0, 2.0, 3.0, 4.0);
3619
3620 let mut registry = TypeRegistry::default();
3621 registry.register::<f32>();
3622 registry.register::<Quat>();
3623
3624 let ser = ReflectSerializer::new(&q, ®istry);
3625
3626 let config = PrettyConfig::default()
3627 .new_line(String::from("\n"))
3628 .indentor(String::from(" "));
3629 let output = to_string_pretty(&ser, config).unwrap();
3630 let expected = r#"
3631{
3632 "glam::Quat": (1.0, 2.0, 3.0, 4.0),
3633}"#;
3634
3635 assert_eq!(expected, format!("\n{output}"));
3636 }
3637
3638 #[test]
3639 fn quat_deserialization() {
3640 let data = r#"
3641{
3642 "glam::Quat": (1.0, 2.0, 3.0, 4.0),
3643}"#;
3644
3645 let mut registry = TypeRegistry::default();
3646 registry.register::<Quat>();
3647 registry.register::<f32>();
3648
3649 let de = ReflectDeserializer::new(®istry);
3650
3651 let mut deserializer =
3652 Deserializer::from_str(data).expect("Failed to acquire deserializer");
3653
3654 let dynamic_struct = de
3655 .deserialize(&mut deserializer)
3656 .expect("Failed to deserialize");
3657
3658 let mut result = Quat::default();
3659
3660 result.apply(dynamic_struct.as_partial_reflect());
3661
3662 assert_eq!(result, quat(1.0, 2.0, 3.0, 4.0));
3663 }
3664
3665 #[test]
3666 fn vec3_serialization() {
3667 let v = vec3(12.0, 3.0, -6.9);
3668
3669 let mut registry = TypeRegistry::default();
3670 registry.register::<f32>();
3671 registry.register::<Vec3>();
3672
3673 let ser = ReflectSerializer::new(&v, ®istry);
3674
3675 let config = PrettyConfig::default()
3676 .new_line(String::from("\n"))
3677 .indentor(String::from(" "));
3678 let output = to_string_pretty(&ser, config).unwrap();
3679 let expected = r#"
3680{
3681 "glam::Vec3": (12.0, 3.0, -6.9),
3682}"#;
3683
3684 assert_eq!(expected, format!("\n{output}"));
3685 }
3686
3687 #[test]
3688 fn vec3_deserialization() {
3689 let data = r#"
3690{
3691 "glam::Vec3": (12.0, 3.0, -6.9),
3692}"#;
3693
3694 let mut registry = TypeRegistry::default();
3695 registry.add_registration(Vec3::get_type_registration());
3696 registry.add_registration(f32::get_type_registration());
3697
3698 let de = ReflectDeserializer::new(®istry);
3699
3700 let mut deserializer =
3701 Deserializer::from_str(data).expect("Failed to acquire deserializer");
3702
3703 let dynamic_struct = de
3704 .deserialize(&mut deserializer)
3705 .expect("Failed to deserialize");
3706
3707 let mut result = Vec3::default();
3708
3709 result.apply(dynamic_struct.as_partial_reflect());
3710
3711 assert_eq!(result, vec3(12.0, 3.0, -6.9));
3712 }
3713
3714 #[test]
3715 fn vec3_field_access() {
3716 let mut v = vec3(1.0, 2.0, 3.0);
3717
3718 assert_eq!(*v.get_field::<f32>("x").unwrap(), 1.0);
3719
3720 *v.get_field_mut::<f32>("y").unwrap() = 6.0;
3721
3722 assert_eq!(v.y, 6.0);
3723 }
3724
3725 #[test]
3726 fn vec3_path_access() {
3727 let mut v = vec3(1.0, 2.0, 3.0);
3728
3729 assert_eq!(
3730 *v.reflect_path("x")
3731 .unwrap()
3732 .try_downcast_ref::<f32>()
3733 .unwrap(),
3734 1.0
3735 );
3736
3737 *v.reflect_path_mut("y")
3738 .unwrap()
3739 .try_downcast_mut::<f32>()
3740 .unwrap() = 6.0;
3741
3742 assert_eq!(v.y, 6.0);
3743 }
3744
3745 #[test]
3746 fn vec3_apply_dynamic() {
3747 let mut v = vec3(3.0, 3.0, 3.0);
3748
3749 let mut d = DynamicStruct::default();
3750 d.insert("x", 4.0f32);
3751 d.insert("y", 2.0f32);
3752 d.insert("z", 1.0f32);
3753
3754 v.apply(&d);
3755
3756 assert_eq!(v, vec3(4.0, 2.0, 1.0));
3757 }
3758 }
3759}