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(rustdoc_internals))]
9#![cfg_attr(docsrs, feature(doc_cfg))]
10#![doc(
11 html_logo_url = "https://bevy.org/assets/icon.png",
12 html_favicon_url = "https://bevy.org/assets/icon.png"
13)]
14
15#![no_std]
589
590#[cfg(feature = "std")]
591extern crate std;
592
593extern crate alloc;
594
595extern crate self as bevy_reflect;
597
598pub mod array;
599pub mod display;
600mod error;
601mod fields;
602mod from_reflect;
603#[cfg(feature = "functions")]
604pub mod func;
605mod is;
606mod kind;
607pub mod list;
608pub mod map;
609mod path;
610mod reflect;
611mod reflectable;
612mod remote;
613pub mod set;
614pub mod structs;
615pub mod tuple;
616pub mod tuple_struct;
617mod type_data;
618mod type_path;
619mod type_registry;
620
621mod impls {
622 mod alloc;
623 mod bevy_platform;
624 mod core;
625 mod foldhash;
626 #[cfg(feature = "hashbrown")]
627 mod hashbrown;
628 mod macros;
629 #[cfg(feature = "std")]
630 mod std;
631
632 #[cfg(feature = "glam")]
633 mod glam;
634 #[cfg(feature = "indexmap")]
635 mod indexmap;
636 #[cfg(feature = "petgraph")]
637 mod petgraph;
638 #[cfg(feature = "smallvec")]
639 mod smallvec;
640 #[cfg(feature = "smol_str")]
641 mod smol_str;
642 #[cfg(feature = "uuid")]
643 mod uuid;
644 #[cfg(feature = "wgpu-types")]
645 mod wgpu_types;
646}
647
648pub mod attributes;
649pub mod convert;
650pub mod enums;
651mod generics;
652mod info;
653pub mod serde;
654pub mod std_traits;
655pub mod ty;
656#[cfg(feature = "debug_stack")]
657mod type_info_stack;
658pub mod utility;
659
660pub mod prelude {
664 pub use crate::std_traits::*;
665
666 #[doc(hidden)]
667 pub use crate::{
668 reflect_trait,
669 structs::{GetField, Struct},
670 tuple_struct::{GetTupleStructField, TupleStruct},
671 FromReflect, GetPath, PartialReflect, Reflect, ReflectDeserialize, ReflectFromReflect,
672 ReflectPath, ReflectSerialize, TypePath,
673 };
674
675 #[cfg(feature = "functions")]
676 pub use crate::func::{Function, IntoFunction, IntoFunctionMut};
677}
678
679pub use error::*;
680pub use fields::*;
681pub use from_reflect::*;
682pub use generics::*;
683pub use info::*;
684pub use is::*;
685pub use kind::*;
686pub use path::*;
687pub use reflect::*;
688pub use reflectable::*;
689pub use remote::*;
690pub use ty::*;
691pub use type_data::*;
692pub use type_path::*;
693pub use type_registry::*;
694
695pub use bevy_reflect_derive::*;
696pub use erased_serde;
697
698#[doc(hidden)]
702pub mod __macro_exports {
703 use crate::{
704 array::DynamicArray, enums::DynamicEnum, list::DynamicList, map::DynamicMap,
705 structs::DynamicStruct, tuple::DynamicTuple, tuple_struct::DynamicTupleStruct,
706 GetTypeRegistration, TypeRegistry,
707 };
708
709 pub mod alloc_utils {
714 pub use ::alloc::{
715 borrow::{Cow, ToOwned},
716 boxed::Box,
717 format,
718 string::ToString,
719 };
720 }
721
722 #[diagnostic::on_unimplemented(
731 message = "`{Self}` does not implement `GetTypeRegistration` so cannot be registered for reflection",
732 note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
733 )]
734 pub trait RegisterForReflection {
735 #[expect(
736 unused_variables,
737 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."
738 )]
739 fn __register(registry: &mut TypeRegistry) {}
740 }
741
742 impl<T: GetTypeRegistration> RegisterForReflection for T {
743 fn __register(registry: &mut TypeRegistry) {
744 registry.register::<T>();
745 }
746 }
747
748 impl RegisterForReflection for DynamicEnum {}
749
750 impl RegisterForReflection for DynamicTupleStruct {}
751
752 impl RegisterForReflection for DynamicStruct {}
753
754 impl RegisterForReflection for DynamicMap {}
755
756 impl RegisterForReflection for DynamicList {}
757
758 impl RegisterForReflection for DynamicArray {}
759
760 impl RegisterForReflection for DynamicTuple {}
761
762 #[cfg(feature = "auto_register")]
764 pub mod auto_register {
765 pub use super::*;
766
767 #[cfg(all(
768 not(feature = "auto_register_inventory"),
769 not(feature = "auto_register_static")
770 ))]
771 compile_error!(
772 "Choosing a backend is required for automatic reflect registration. Please enable either the \"auto_register_inventory\" or the \"auto_register_static\" feature."
773 );
774
775 #[cfg(all(
777 not(feature = "auto_register_static"),
778 feature = "auto_register_inventory"
779 ))]
780 mod __automatic_type_registration_impl {
781 use super::*;
782
783 pub use ::inventory;
784
785 pub struct AutomaticReflectRegistrations(pub fn(&mut TypeRegistry));
787
788 pub fn register_types(registry: &mut TypeRegistry) {
790 #[cfg(target_family = "wasm")]
791 wasm_support::init();
792 for registration_fn in inventory::iter::<AutomaticReflectRegistrations> {
793 registration_fn.0(registry);
794 }
795 }
796
797 inventory::collect!(AutomaticReflectRegistrations);
798
799 #[cfg(target_family = "wasm")]
800 mod wasm_support {
801 use bevy_platform::sync::atomic::{AtomicBool, Ordering};
802
803 static INIT_DONE: AtomicBool = AtomicBool::new(false);
804
805 #[expect(unsafe_code, reason = "This function is generated by linker.")]
806 unsafe extern "C" {
807 fn __wasm_call_ctors();
808 }
809
810 pub fn init() {
812 if INIT_DONE.swap(true, Ordering::Relaxed) {
813 return;
814 };
815 #[expect(
816 unsafe_code,
817 reason = "This function must be called to use inventory on wasm."
818 )]
819 unsafe {
824 __wasm_call_ctors();
825 }
826 }
827 }
828 }
829
830 #[cfg(feature = "auto_register_static")]
832 mod __automatic_type_registration_impl {
833 use super::*;
834 use alloc::vec::Vec;
835 use bevy_platform::sync::Mutex;
836
837 static REGISTRATION_FNS: Mutex<Vec<fn(&mut TypeRegistry)>> = Mutex::new(Vec::new());
838
839 pub fn push_registration_fn(registration_fn: fn(&mut TypeRegistry)) {
841 REGISTRATION_FNS.lock().unwrap().push(registration_fn);
842 }
843
844 pub fn register_types(registry: &mut TypeRegistry) {
846 for func in REGISTRATION_FNS.lock().unwrap().iter() {
847 (func)(registry);
848 }
849 }
850 }
851
852 #[cfg(any(feature = "auto_register_static", feature = "auto_register_inventory"))]
853 pub use __automatic_type_registration_impl::*;
854 }
855}
856
857#[cfg(test)]
858#[expect(
859 clippy::approx_constant,
860 reason = "We don't need the exact value of Pi here."
861)]
862mod tests {
863 use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
864 use alloc::{
865 borrow::Cow,
866 boxed::Box,
867 format,
868 string::{String, ToString},
869 vec,
870 vec::Vec,
871 };
872 use bevy_platform::collections::HashMap;
873 use core::{
874 any::TypeId,
875 fmt::{Debug, Formatter},
876 hash::Hash,
877 marker::PhantomData,
878 };
879 use disqualified::ShortName;
880 use ron::{
881 ser::{to_string_pretty, PrettyConfig},
882 Deserializer,
883 };
884 use static_assertions::{assert_impl_all, assert_not_impl_all};
885
886 use super::{
887 array::*, enums::*, list::*, map::*, prelude::*, structs::*, tuple::*, tuple_struct::*, *,
888 };
889 use crate::{
890 serde::{ReflectDeserializer, ReflectSerializer},
891 utility::GenericTypePathCell,
892 };
893
894 #[test]
895 fn try_apply_should_detect_kinds() {
896 #[derive(Reflect, Debug)]
897 struct Struct {
898 a: u32,
899 b: f32,
900 }
901
902 #[derive(Reflect, Debug)]
903 enum Enum {
904 A,
905 B(u32),
906 }
907
908 let mut struct_target = Struct {
909 a: 0xDEADBEEF,
910 b: 3.14,
911 };
912
913 let mut enum_target = Enum::A;
914
915 let array_src = [8, 0, 8];
916
917 let result = struct_target.try_apply(&enum_target);
918 assert!(
919 matches!(
920 result,
921 Err(ApplyError::MismatchedKinds {
922 from_kind: ReflectKind::Enum,
923 to_kind: ReflectKind::Struct
924 })
925 ),
926 "result was {result:?}"
927 );
928
929 let result = enum_target.try_apply(&array_src);
930 assert!(
931 matches!(
932 result,
933 Err(ApplyError::MismatchedKinds {
934 from_kind: ReflectKind::Array,
935 to_kind: ReflectKind::Enum
936 })
937 ),
938 "result was {result:?}"
939 );
940 }
941
942 #[test]
943 fn reflect_struct() {
944 #[derive(Reflect)]
945 struct Foo {
946 a: u32,
947 b: f32,
948 c: Bar,
949 }
950 #[derive(Reflect)]
951 struct Bar {
952 x: u32,
953 }
954
955 let mut foo = Foo {
956 a: 42,
957 b: 3.14,
958 c: Bar { x: 1 },
959 };
960
961 let a = *foo.get_field::<u32>("a").unwrap();
962 assert_eq!(a, 42);
963
964 *foo.get_field_mut::<u32>("a").unwrap() += 1;
965 assert_eq!(foo.a, 43);
966
967 let bar = foo.get_field::<Bar>("c").unwrap();
968 assert_eq!(bar.x, 1);
969
970 let c = foo.field("c").unwrap();
972 let value = c.reflect_ref().as_struct().unwrap();
973 assert_eq!(*value.get_field::<u32>("x").unwrap(), 1);
974
975 let mut dynamic_struct = DynamicStruct::default();
977 dynamic_struct.insert("a", 123u32);
978 dynamic_struct.insert("should_be_ignored", 456);
979
980 foo.apply(&dynamic_struct);
981 assert_eq!(foo.a, 123);
982 }
983
984 #[test]
985 fn reflect_map() {
986 #[derive(Reflect, Hash)]
987 #[reflect(Hash)]
988 struct Foo {
989 a: u32,
990 b: String,
991 }
992
993 let key_a = Foo {
994 a: 1,
995 b: "k1".to_string(),
996 };
997
998 let key_b = Foo {
999 a: 1,
1000 b: "k1".to_string(),
1001 };
1002
1003 let key_c = Foo {
1004 a: 3,
1005 b: "k3".to_string(),
1006 };
1007
1008 let mut map = DynamicMap::default();
1009 map.insert(key_a, 10u32);
1010 assert_eq!(
1011 10,
1012 *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
1013 );
1014 assert!(map.get(&key_c).is_none());
1015 *map.get_mut(&key_b)
1016 .unwrap()
1017 .try_downcast_mut::<u32>()
1018 .unwrap() = 20;
1019 assert_eq!(
1020 20,
1021 *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
1022 );
1023 }
1024
1025 #[test]
1026 fn reflect_unit_struct() {
1027 #[derive(Reflect)]
1028 struct Foo(u32, u64);
1029
1030 let mut foo = Foo(1, 2);
1031 assert_eq!(1, *foo.get_field::<u32>(0).unwrap());
1032 assert_eq!(2, *foo.get_field::<u64>(1).unwrap());
1033
1034 let mut patch = DynamicTupleStruct::default();
1035 patch.insert(3u32);
1036 patch.insert(4u64);
1037 assert_eq!(
1038 3,
1039 *patch.field(0).unwrap().try_downcast_ref::<u32>().unwrap()
1040 );
1041 assert_eq!(
1042 4,
1043 *patch.field(1).unwrap().try_downcast_ref::<u64>().unwrap()
1044 );
1045
1046 foo.apply(&patch);
1047 assert_eq!(3, foo.0);
1048 assert_eq!(4, foo.1);
1049
1050 let mut iter = patch.iter_fields();
1051 assert_eq!(3, *iter.next().unwrap().try_downcast_ref::<u32>().unwrap());
1052 assert_eq!(4, *iter.next().unwrap().try_downcast_ref::<u64>().unwrap());
1053 }
1054
1055 #[test]
1056 #[should_panic(
1057 expected = "the given key of type `bevy_reflect::tests::Foo` does not support hashing"
1058 )]
1059 fn reflect_map_no_hash() {
1060 #[derive(Reflect)]
1061 struct Foo {
1062 a: u32,
1063 }
1064
1065 let foo = Foo { a: 1 };
1066 assert!(foo.reflect_hash().is_none());
1067
1068 let mut map = DynamicMap::default();
1069 map.insert(foo, 10u32);
1070 }
1071
1072 #[test]
1073 #[should_panic(
1074 expected = "the dynamic type `bevy_reflect::DynamicStruct` (representing `bevy_reflect::tests::Foo`) does not support hashing"
1075 )]
1076 fn reflect_map_no_hash_dynamic_representing() {
1077 #[derive(Reflect, Hash)]
1078 #[reflect(Hash)]
1079 struct Foo {
1080 a: u32,
1081 }
1082
1083 let foo = Foo { a: 1 };
1084 assert!(foo.reflect_hash().is_some());
1085 let dynamic = foo.to_dynamic_struct().unwrap();
1086
1087 let mut map = DynamicMap::default();
1088 map.insert(dynamic, 11u32);
1089 }
1090
1091 #[test]
1092 #[should_panic(
1093 expected = "the dynamic type `bevy_reflect::DynamicStruct` does not support hashing"
1094 )]
1095 fn reflect_map_no_hash_dynamic() {
1096 #[allow(
1097 clippy::allow_attributes,
1098 dead_code,
1099 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1100 )]
1101 #[derive(Reflect, Hash)]
1102 #[reflect(Hash)]
1103 struct Foo {
1104 a: u32,
1105 }
1106
1107 let mut dynamic = DynamicStruct::default();
1108 dynamic.insert("a", 4u32);
1109 assert!(dynamic.reflect_hash().is_none());
1110
1111 let mut map = DynamicMap::default();
1112 map.insert(dynamic, 11u32);
1113 }
1114
1115 #[test]
1116 fn reflect_ignore() {
1117 #[derive(Reflect)]
1118 struct Foo {
1119 a: u32,
1120 #[reflect(ignore)]
1121 _b: u32,
1122 }
1123
1124 let foo = Foo { a: 1, _b: 2 };
1125
1126 let values: Vec<u32> = foo
1127 .iter_fields()
1128 .map(|(_, value)| *value.try_downcast_ref::<u32>().unwrap())
1129 .collect();
1130 assert_eq!(values, vec![1]);
1131 }
1132
1133 #[test]
1147 fn should_reflect_generic() {
1148 struct FakeString {}
1149
1150 impl core::ops::Add<FakeString> for String {
1152 type Output = Self;
1153 fn add(self, _rhs: FakeString) -> Self::Output {
1154 unreachable!()
1155 }
1156 }
1157
1158 #[expect(
1159 dead_code,
1160 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1161 )]
1162 #[derive(Reflect)]
1163 struct Foo<A>(A);
1164
1165 #[expect(
1166 dead_code,
1167 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1168 )]
1169 #[derive(Reflect)]
1170 struct Bar<A, B>(A, B);
1171
1172 #[expect(
1173 dead_code,
1174 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1175 )]
1176 #[derive(Reflect)]
1177 struct Baz<A, B, C>(A, B, C);
1178 }
1179
1180 #[test]
1181 fn should_reflect_clone() {
1182 #[derive(Reflect, Debug, PartialEq)]
1184 struct Foo(usize);
1185
1186 let value = Foo(123);
1187 let clone = value.reflect_clone().expect("should reflect_clone struct");
1188 assert_eq!(value, clone.take::<Foo>().unwrap());
1189
1190 let foo = (123, 4.56);
1192 let clone = foo.reflect_clone().expect("should reflect_clone tuple");
1193 assert_eq!(foo, clone.take::<(u32, f32)>().unwrap());
1194 }
1195
1196 #[test]
1197 fn should_reflect_clone_generic_type() {
1198 #[derive(Reflect, Debug, PartialEq)]
1199 struct Foo<T, U>(T, #[reflect(ignore, clone)] PhantomData<U>);
1200 #[derive(TypePath, Debug, PartialEq)]
1201 struct Bar;
1202
1203 let value = Foo::<usize, Bar>(123, PhantomData);
1206 let clone = value
1207 .reflect_clone()
1208 .expect("should reflect_clone generic struct");
1209 assert_eq!(value, clone.take::<Foo<usize, Bar>>().unwrap());
1210 }
1211
1212 #[test]
1213 fn should_reflect_clone_with_clone() {
1214 #[expect(
1217 dead_code,
1218 reason = "if things are working correctly, this function should never be called"
1219 )]
1220 fn custom_clone(_value: &usize) -> usize {
1221 panic!("should not be called");
1222 }
1223
1224 #[derive(Reflect, Clone, Debug, PartialEq)]
1226 #[reflect(Clone)]
1227 struct Foo(#[reflect(clone = "custom_clone")] usize);
1228
1229 let value = Foo(123);
1230 let clone = value
1231 .reflect_clone()
1232 .expect("should reflect_clone tuple struct");
1233 assert_eq!(value, clone.take::<Foo>().unwrap());
1234
1235 #[derive(Reflect, Clone, Debug, PartialEq)]
1237 #[reflect(Clone)]
1238 struct Bar {
1239 #[reflect(clone = "custom_clone")]
1240 value: usize,
1241 }
1242
1243 let value = Bar { value: 123 };
1244 let clone = value.reflect_clone().expect("should reflect_clone struct");
1245 assert_eq!(value, clone.take::<Bar>().unwrap());
1246
1247 #[derive(Reflect, Clone, Debug, PartialEq)]
1249 #[reflect(Clone)]
1250 enum Baz {
1251 Unit,
1252 Tuple(#[reflect(clone = "custom_clone")] usize),
1253 Struct {
1254 #[reflect(clone = "custom_clone")]
1255 value: usize,
1256 },
1257 }
1258
1259 let value = Baz::Unit;
1260 let clone = value
1261 .reflect_clone()
1262 .expect("should reflect_clone unit variant");
1263 assert_eq!(value, clone.take::<Baz>().unwrap());
1264
1265 let value = Baz::Tuple(123);
1266 let clone = value
1267 .reflect_clone()
1268 .expect("should reflect_clone tuple variant");
1269 assert_eq!(value, clone.take::<Baz>().unwrap());
1270
1271 let value = Baz::Struct { value: 123 };
1272 let clone = value
1273 .reflect_clone()
1274 .expect("should reflect_clone struct variant");
1275 assert_eq!(value, clone.take::<Baz>().unwrap());
1276 }
1277
1278 #[test]
1279 fn should_custom_reflect_clone() {
1280 #[derive(Reflect, Debug, PartialEq)]
1281 #[reflect(Clone(clone_foo))]
1282 struct Foo(usize);
1283
1284 fn clone_foo(foo: &Foo) -> Foo {
1285 Foo(foo.0 + 198)
1286 }
1287
1288 let foo = Foo(123);
1289 let clone = foo.reflect_clone().unwrap();
1290 assert_eq!(Foo(321), clone.take::<Foo>().unwrap());
1291 }
1292
1293 #[test]
1294 fn should_not_clone_ignored_fields() {
1295 #[derive(Reflect, Clone, Debug, PartialEq)]
1297 struct Foo(#[reflect(ignore)] usize);
1298
1299 let foo = Foo(123);
1300 let clone = foo.reflect_clone();
1301 assert_eq!(
1302 clone.unwrap_err(),
1303 ReflectCloneError::FieldNotCloneable {
1304 field: FieldId::Unnamed(0),
1305 variant: None,
1306 container_type_path: Cow::Borrowed(Foo::type_path()),
1307 }
1308 );
1309
1310 #[derive(Reflect, Clone, Debug, PartialEq)]
1312 struct Bar {
1313 #[reflect(ignore)]
1314 value: usize,
1315 }
1316
1317 let bar = Bar { value: 123 };
1318 let clone = bar.reflect_clone();
1319 assert_eq!(
1320 clone.unwrap_err(),
1321 ReflectCloneError::FieldNotCloneable {
1322 field: FieldId::Named(Cow::Borrowed("value")),
1323 variant: None,
1324 container_type_path: Cow::Borrowed(Bar::type_path()),
1325 }
1326 );
1327
1328 #[derive(Reflect, Clone, Debug, PartialEq)]
1330 enum Baz {
1331 Tuple(#[reflect(ignore)] usize),
1332 Struct {
1333 #[reflect(ignore)]
1334 value: usize,
1335 },
1336 }
1337
1338 let baz = Baz::Tuple(123);
1339 let clone = baz.reflect_clone();
1340 assert_eq!(
1341 clone.unwrap_err(),
1342 ReflectCloneError::FieldNotCloneable {
1343 field: FieldId::Unnamed(0),
1344 variant: Some(Cow::Borrowed("Tuple")),
1345 container_type_path: Cow::Borrowed(Baz::type_path()),
1346 }
1347 );
1348
1349 let baz = Baz::Struct { value: 123 };
1350 let clone = baz.reflect_clone();
1351 assert_eq!(
1352 clone.unwrap_err(),
1353 ReflectCloneError::FieldNotCloneable {
1354 field: FieldId::Named(Cow::Borrowed("value")),
1355 variant: Some(Cow::Borrowed("Struct")),
1356 container_type_path: Cow::Borrowed(Baz::type_path()),
1357 }
1358 );
1359 }
1360
1361 #[test]
1362 fn should_clone_ignored_fields_with_clone_attributes() {
1363 #[derive(Reflect, Clone, Debug, PartialEq)]
1364 struct Foo(#[reflect(ignore, clone)] usize);
1365
1366 let foo = Foo(123);
1367 let clone = foo.reflect_clone().unwrap();
1368 assert_eq!(Foo(123), clone.take::<Foo>().unwrap());
1369
1370 #[derive(Reflect, Clone, Debug, PartialEq)]
1371 struct Bar(#[reflect(ignore, clone = "clone_usize")] usize);
1372
1373 fn clone_usize(this: &usize) -> usize {
1374 *this + 198
1375 }
1376
1377 let bar = Bar(123);
1378 let clone = bar.reflect_clone().unwrap();
1379 assert_eq!(Bar(321), clone.take::<Bar>().unwrap());
1380 }
1381
1382 #[test]
1383 fn should_composite_reflect_clone() {
1384 #[derive(Reflect, Debug, PartialEq)]
1385 enum MyEnum {
1386 Unit,
1387 Tuple(
1388 Foo,
1389 #[reflect(ignore, clone)] Bar,
1390 #[reflect(clone = "clone_baz")] Baz,
1391 ),
1392 Struct {
1393 foo: Foo,
1394 #[reflect(ignore, clone)]
1395 bar: Bar,
1396 #[reflect(clone = "clone_baz")]
1397 baz: Baz,
1398 },
1399 }
1400
1401 #[derive(Reflect, Debug, PartialEq)]
1402 struct Foo {
1403 #[reflect(clone = "clone_bar")]
1404 bar: Bar,
1405 baz: Baz,
1406 }
1407
1408 #[derive(Reflect, Default, Clone, Debug, PartialEq)]
1409 #[reflect(Clone)]
1410 struct Bar(String);
1411
1412 #[derive(Reflect, Debug, PartialEq)]
1413 struct Baz(String);
1414
1415 fn clone_bar(bar: &Bar) -> Bar {
1416 Bar(format!("{}!", bar.0))
1417 }
1418
1419 fn clone_baz(baz: &Baz) -> Baz {
1420 Baz(format!("{}!", baz.0))
1421 }
1422
1423 let my_enum = MyEnum::Unit;
1424 let clone = my_enum.reflect_clone().unwrap();
1425 assert_eq!(MyEnum::Unit, clone.take::<MyEnum>().unwrap());
1426
1427 let my_enum = MyEnum::Tuple(
1428 Foo {
1429 bar: Bar("bar".to_string()),
1430 baz: Baz("baz".to_string()),
1431 },
1432 Bar("bar".to_string()),
1433 Baz("baz".to_string()),
1434 );
1435 let clone = my_enum.reflect_clone().unwrap();
1436 assert_eq!(
1437 MyEnum::Tuple(
1438 Foo {
1439 bar: Bar("bar!".to_string()),
1440 baz: Baz("baz".to_string()),
1441 },
1442 Bar("bar".to_string()),
1443 Baz("baz!".to_string()),
1444 ),
1445 clone.take::<MyEnum>().unwrap()
1446 );
1447
1448 let my_enum = MyEnum::Struct {
1449 foo: Foo {
1450 bar: Bar("bar".to_string()),
1451 baz: Baz("baz".to_string()),
1452 },
1453 bar: Bar("bar".to_string()),
1454 baz: Baz("baz".to_string()),
1455 };
1456 let clone = my_enum.reflect_clone().unwrap();
1457 assert_eq!(
1458 MyEnum::Struct {
1459 foo: Foo {
1460 bar: Bar("bar!".to_string()),
1461 baz: Baz("baz".to_string()),
1462 },
1463 bar: Bar("bar".to_string()),
1464 baz: Baz("baz!".to_string()),
1465 },
1466 clone.take::<MyEnum>().unwrap()
1467 );
1468 }
1469
1470 #[test]
1471 fn reflect_partial_cmp_derive_support() {
1472 use core::cmp::Ordering;
1473
1474 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1475 #[reflect(PartialOrd)]
1476 struct Foo(i32);
1477
1478 let a = Foo(1);
1479 let b = Foo(2);
1480
1481 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1483 assert_eq!(ord, Some(Ordering::Less));
1484
1485 let ord_mismatch = PartialReflect::reflect_partial_cmp(&a, &1i32);
1487 assert_eq!(ord_mismatch, None);
1488 }
1489
1490 #[test]
1491 fn reflect_partial_cmp_custom_fn() {
1492 use core::cmp::Ordering;
1493
1494 fn custom_cmp(a: &CustomFoo, b: &dyn PartialReflect) -> Option<Ordering> {
1495 if let Some(b) = b.try_downcast_ref::<CustomFoo>() {
1496 Some(::core::cmp::Ord::cmp(&a.0, &b.0))
1497 } else {
1498 Some(Ordering::Greater)
1499 }
1500 }
1501
1502 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1503 #[reflect(PartialOrd(custom_cmp))]
1504 struct CustomFoo(i32);
1505
1506 let a = CustomFoo(3);
1507 let b = CustomFoo(5);
1508
1509 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1510 assert_eq!(ord, Some(Ordering::Less));
1511
1512 let ord_mismatch = PartialReflect::reflect_partial_cmp(&a, &1i32);
1513 assert_eq!(ord_mismatch, Some(Ordering::Greater));
1514 }
1515
1516 #[test]
1517 fn reflect_partial_cmp_array() {
1518 use core::cmp::Ordering;
1519
1520 let a = [1i32, 2];
1521 let b = [1i32, 3];
1522
1523 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1524 assert_eq!(ord, Some(Ordering::Less));
1525 }
1526
1527 #[test]
1528 fn reflect_partial_cmp_tuple_length_mismatch() {
1529 let a = (1i32, 2i32);
1531 let b = (1i32, 2i32, 3i32);
1532
1533 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1534 assert_eq!(ord, None);
1535 }
1536
1537 #[test]
1538 fn reflect_partial_cmp_btreemap_lexicographic() {
1539 use alloc::collections::BTreeMap;
1540 use core::cmp::Ordering;
1541
1542 let mut m1: BTreeMap<usize, i32> = BTreeMap::new();
1543 m1.insert(1usize, 1i32);
1544 m1.insert(2usize, 3i32);
1545
1546 let mut m2: BTreeMap<usize, i32> = BTreeMap::new();
1547 m2.insert(1usize, 1i32);
1548 m2.insert(2usize, 4i32);
1549
1550 let ord = PartialReflect::reflect_partial_cmp(&m1, &m2);
1551 assert_eq!(ord, Some(Ordering::Less));
1552 }
1553
1554 #[test]
1555 fn reflect_partial_cmp_btreemap_key_difference() {
1556 use alloc::collections::BTreeMap;
1557 use core::cmp::Ordering;
1558
1559 let mut m1: BTreeMap<usize, i32> = BTreeMap::new();
1560 m1.insert(1usize, 10i32);
1561
1562 let mut m2: BTreeMap<usize, i32> = BTreeMap::new();
1563 m2.insert(2usize, 5i32);
1564
1565 let ord = PartialReflect::reflect_partial_cmp(&m1, &m2);
1567 assert_eq!(ord, Some(Ordering::Less));
1568 }
1569
1570 #[test]
1571 fn reflect_partial_cmp_btreemap_length_difference() {
1572 use alloc::collections::BTreeMap;
1573 use core::cmp::Ordering;
1574
1575 let mut m1: BTreeMap<usize, i32> = BTreeMap::new();
1576 m1.insert(1usize, 1i32);
1577 m1.insert(2usize, 2i32);
1578
1579 let mut m2: BTreeMap<usize, i32> = BTreeMap::new();
1580 m2.insert(1usize, 1i32);
1581
1582 let ord = PartialReflect::reflect_partial_cmp(&m1, &m2);
1584 assert_eq!(ord, Some(Ordering::Greater));
1585 }
1586
1587 #[test]
1588 fn reflect_partial_cmp_btreemap_value_incomparable() {
1589 use alloc::collections::BTreeMap;
1590
1591 let mut m1: BTreeMap<usize, f32> = BTreeMap::new();
1592 m1.insert(1usize, 1.0f32);
1593
1594 let mut m2: BTreeMap<usize, f32> = BTreeMap::new();
1595 m2.insert(1usize, f32::NAN);
1596
1597 assert_eq!(PartialReflect::reflect_partial_cmp(&m1, &m2), None);
1599 }
1600
1601 #[test]
1602 fn reflect_partial_cmp_list_lexicographic() {
1603 use core::cmp::Ordering;
1604
1605 let a = vec![1i32, 2];
1606 let b = vec![1i32, 3];
1607
1608 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1609 assert_eq!(ord, Some(Ordering::Less));
1610 }
1611
1612 #[test]
1613 fn reflect_partial_cmp_tuple_lexicographic() {
1614 use core::cmp::Ordering;
1615
1616 let a = (1i32, 2i32);
1617 let b = (1i32, 3i32);
1618
1619 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1620 assert_eq!(ord, Some(Ordering::Less));
1621 }
1622
1623 #[test]
1624 fn reflect_partial_cmp_tuple_struct_and_mismatch() {
1625 use core::cmp::Ordering;
1626
1627 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1628 #[reflect(PartialOrd)]
1629 struct TS(i32, i32);
1630
1631 let a = TS(1, 2);
1632 let b = TS(1, 3);
1633
1634 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1635 assert_eq!(ord, Some(Ordering::Less));
1636
1637 let ord_mismatch = PartialReflect::reflect_partial_cmp(&a, &(1i32, 2i32));
1639 assert_eq!(ord_mismatch, None);
1640
1641 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1644 struct TSNoAttr(i32, i32);
1645
1646 let a2 = TSNoAttr(1, 2);
1647 let b2 = TSNoAttr(1, 3);
1648
1649 let ord2 = PartialReflect::reflect_partial_cmp(&a2, &b2);
1650 assert_eq!(ord2, Some(Ordering::Less));
1651
1652 let ord2_mismatch = PartialReflect::reflect_partial_cmp(&a2, &(1i32, 2i32));
1653 assert_eq!(ord2_mismatch, None);
1654 }
1655
1656 #[test]
1657 fn reflect_partial_cmp_struct_fields() {
1658 use core::cmp::Ordering;
1659
1660 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1661 #[reflect(PartialOrd)]
1662 struct S {
1663 a: i32,
1664 b: i32,
1665 }
1666
1667 let a = S { a: 1, b: 2 };
1668 let b = S { a: 1, b: 3 };
1669
1670 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1671 assert_eq!(ord, Some(Ordering::Less));
1672
1673 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1675 struct SNoAttr {
1676 a: i32,
1677 b: i32,
1678 }
1679
1680 let a2 = SNoAttr { a: 1, b: 2 };
1681 let b2 = SNoAttr { a: 1, b: 3 };
1682
1683 let ord2 = PartialReflect::reflect_partial_cmp(&a2, &b2);
1684 assert_eq!(ord2, Some(Ordering::Less));
1685 }
1686
1687 #[test]
1688 fn enum_variant_ordering() {
1689 use core::cmp::Ordering;
1690
1691 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1692 enum MyEnum {
1693 Top,
1694 Center,
1695 Bottom,
1696 }
1697
1698 let a = MyEnum::Top;
1699 let b = MyEnum::Center;
1700 let c = MyEnum::Bottom;
1701
1702 assert_eq!(PartialReflect::reflect_partial_cmp(&a, &b), None);
1704 assert_eq!(PartialReflect::reflect_partial_cmp(&b, &a), None);
1705 assert_eq!(PartialReflect::reflect_partial_cmp(&b, &c), None);
1706 assert_eq!(
1707 PartialReflect::reflect_partial_cmp(&a, &a),
1708 Some(Ordering::Equal)
1709 );
1710
1711 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1712 enum MyEnum2 {
1713 A,
1714 B,
1715 Center,
1716 }
1717 let a1 = MyEnum2::A;
1718 let c1 = MyEnum2::Center;
1719
1720 assert_eq!(PartialReflect::reflect_partial_cmp(&a1, &a), None);
1721 assert_eq!(PartialReflect::reflect_partial_cmp(&a1, &b), None);
1722 assert_eq!(
1724 PartialReflect::reflect_partial_cmp(&c1, &b),
1725 Some(Ordering::Equal)
1726 );
1727 }
1728
1729 #[test]
1730 fn enum_from_reflect_does_not_panic() {
1731 #[derive(Reflect, PartialEq, Eq, Debug)]
1732 enum A {
1733 Hot,
1734 Cold,
1735 }
1736
1737 #[derive(Reflect, PartialEq, Eq, Debug)]
1738 enum B {
1739 Hot,
1740 Cold,
1741 Warm,
1742 }
1743
1744 assert_eq!(A::from_reflect(&B::Hot), Some(A::Hot));
1747 assert_eq!(A::from_reflect(&B::Cold), Some(A::Cold));
1748 assert_eq!(A::from_reflect(&B::Warm), None);
1750 }
1751
1752 #[test]
1753 fn reflect_partial_cmp_array_length_difference() {
1754 use core::cmp::Ordering;
1755
1756 let a = [1i32, 2i32];
1757 let b = [1i32, 2i32, 3i32];
1758
1759 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1760 assert_eq!(ord, Some(Ordering::Less));
1761 }
1762
1763 #[test]
1764 fn reflect_partial_cmp_nested_none() {
1765 let a = (1i32, (1f32, f32::NAN));
1767 let b = (1i32, (1f32, 2f32));
1768
1769 assert_eq!(PartialReflect::reflect_partial_cmp(&a, &b), None);
1770 }
1771
1772 #[test]
1773 fn reflect_partial_cmp_struct_named_field_reorder() {
1774 use crate::structs::DynamicStruct;
1775
1776 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1777 struct S {
1778 a: i32,
1779 b: i32,
1780 }
1781
1782 let concrete = S { a: 1, b: 0 };
1783
1784 let mut dyn_s = DynamicStruct::default();
1788 dyn_s.insert("b", 1i32);
1789 dyn_s.insert("a", 0i32);
1790 assert_eq!(PartialReflect::reflect_partial_cmp(&concrete, &dyn_s), None);
1791 assert_eq!(PartialReflect::reflect_partial_cmp(&dyn_s, &concrete), None);
1792
1793 let mut dyn_s = DynamicStruct::default();
1795 dyn_s.insert("b", 0i32);
1796 dyn_s.insert("a", 0i32);
1797 assert_eq!(
1798 PartialReflect::reflect_partial_cmp(&concrete, &dyn_s),
1799 Some(core::cmp::Ordering::Greater)
1800 );
1801
1802 let mut dyn_s = DynamicStruct::default();
1803 dyn_s.insert("b", 0i32);
1804 dyn_s.insert("a", 1i32);
1805 assert_eq!(
1806 PartialReflect::reflect_partial_cmp(&concrete, &dyn_s),
1807 Some(core::cmp::Ordering::Equal)
1808 );
1809 }
1810
1811 #[test]
1812 fn reflect_partial_cmp_enum_variant_type_mismatch() {
1813 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1814 enum E1 {
1815 Foo(i32),
1816 }
1817
1818 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1819 enum E2 {
1820 Foo { x: i32 },
1821 }
1822
1823 let a = E1::Foo(1);
1824 let b = E2::Foo { x: 1 };
1825
1826 assert_eq!(PartialReflect::reflect_partial_cmp(&a, &b), None);
1828 }
1829
1830 #[test]
1831 fn reflect_partial_cmp_dynamic_vs_concrete_struct_equal() {
1832 use crate::structs::DynamicStruct;
1833
1834 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1835 struct S {
1836 a: i32,
1837 b: i32,
1838 }
1839
1840 let concrete = S { a: 5, b: 6 };
1841
1842 let mut dyn_s = DynamicStruct::default();
1843 dyn_s.insert("a", 5i32);
1844 dyn_s.insert("b", 6i32);
1845
1846 assert_eq!(
1847 PartialReflect::reflect_partial_cmp(&concrete, &dyn_s),
1848 Some(core::cmp::Ordering::Equal)
1849 );
1850 }
1851
1852 #[test]
1853 fn reflect_partial_cmp_opaque_without_impl() {
1854 #[derive(Reflect, Debug)]
1855 struct Opaque(usize);
1856
1857 let o = Opaque(1);
1858
1859 assert_eq!(
1861 PartialReflect::reflect_partial_cmp(&o, &o),
1862 Some(core::cmp::Ordering::Equal)
1863 );
1864 }
1865
1866 #[test]
1867 fn reflect_partial_cmp_btreemap_equal_keys_diff_values() {
1868 use alloc::collections::BTreeMap;
1869 use core::cmp::Ordering;
1870
1871 let mut m1: BTreeMap<usize, i32> = BTreeMap::new();
1872 m1.insert(1usize, 2i32);
1873 m1.insert(2usize, 3i32);
1874
1875 let mut m2: BTreeMap<usize, i32> = BTreeMap::new();
1876 m2.insert(1usize, 2i32);
1877 m2.insert(2usize, 4i32);
1878
1879 let ord = PartialReflect::reflect_partial_cmp(&m1, &m2);
1880 assert_eq!(ord, Some(Ordering::Less));
1881 }
1882
1883 #[test]
1884 fn reflect_partial_cmp_large_nested_stress_none() {
1885 use alloc::collections::BTreeMap;
1886
1887 let mut m1: BTreeMap<usize, Vec<(i32, f32)>> = BTreeMap::new();
1889 m1.insert(1usize, vec![(1, 2.0f32), (2, 3.0f32)]);
1890
1891 let mut m2: BTreeMap<usize, Vec<(i32, f32)>> = BTreeMap::new();
1892 m2.insert(1usize, vec![(1, 2.0f32), (2, f32::NAN)]);
1893
1894 assert_eq!(PartialReflect::reflect_partial_cmp(&m1, &m2), None);
1895 }
1896
1897 #[test]
1898 fn reflect_partial_cmp_enum_variant() {
1899 use core::cmp::Ordering;
1900
1901 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1902 #[reflect(PartialOrd)]
1903 enum E {
1904 A(i32),
1905 B,
1906 }
1907
1908 let a = E::A(1);
1909 let b = E::A(2);
1910
1911 let ord = PartialReflect::reflect_partial_cmp(&a, &b);
1912 assert_eq!(ord, Some(Ordering::Less));
1913
1914 #[derive(PartialEq, PartialOrd, Reflect, Debug)]
1917 enum ENoAttr {
1918 A(i32),
1919 B,
1920 }
1921
1922 let a2 = ENoAttr::A(1);
1923 let b2 = ENoAttr::A(2);
1924
1925 let ord2 = PartialReflect::reflect_partial_cmp(&a2, &b2);
1926 assert_eq!(ord2, Some(Ordering::Less));
1927 }
1928
1929 #[test]
1930 fn should_call_from_reflect_dynamically() {
1931 #[derive(Reflect)]
1932 struct MyStruct {
1933 foo: usize,
1934 }
1935
1936 let mut registry = TypeRegistry::default();
1938 registry.register::<MyStruct>();
1939
1940 let type_id = TypeId::of::<MyStruct>();
1942 let rfr = registry
1943 .get_type_data::<ReflectFromReflect>(type_id)
1944 .expect("the FromReflect trait should be registered");
1945
1946 let mut dynamic_struct = DynamicStruct::default();
1948 dynamic_struct.insert("foo", 123usize);
1949 let reflected = rfr
1950 .from_reflect(&dynamic_struct)
1951 .expect("the type should be properly reflected");
1952
1953 let expected = MyStruct { foo: 123 };
1955 assert!(expected
1956 .reflect_partial_eq(reflected.as_partial_reflect())
1957 .unwrap_or_default());
1958 let not_expected = MyStruct { foo: 321 };
1959 assert!(!not_expected
1960 .reflect_partial_eq(reflected.as_partial_reflect())
1961 .unwrap_or_default());
1962 }
1963
1964 #[test]
1965 fn from_reflect_should_allow_ignored_unnamed_fields() {
1966 #[derive(Reflect, Eq, PartialEq, Debug)]
1967 struct MyTupleStruct(i8, #[reflect(ignore)] i16, i32);
1968
1969 let expected = MyTupleStruct(1, 0, 3);
1970
1971 let mut dyn_tuple_struct = DynamicTupleStruct::default();
1972 dyn_tuple_struct.insert(1_i8);
1973 dyn_tuple_struct.insert(3_i32);
1974 let my_tuple_struct = <MyTupleStruct as FromReflect>::from_reflect(&dyn_tuple_struct);
1975
1976 assert_eq!(Some(expected), my_tuple_struct);
1977
1978 #[derive(Reflect, Eq, PartialEq, Debug)]
1979 enum MyEnum {
1980 Tuple(i8, #[reflect(ignore)] i16, i32),
1981 }
1982
1983 let expected = MyEnum::Tuple(1, 0, 3);
1984
1985 let mut dyn_tuple = DynamicTuple::default();
1986 dyn_tuple.insert(1_i8);
1987 dyn_tuple.insert(3_i32);
1988
1989 let mut dyn_enum = DynamicEnum::default();
1990 dyn_enum.set_variant("Tuple", dyn_tuple);
1991
1992 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1993
1994 assert_eq!(Some(expected), my_enum);
1995 }
1996
1997 #[test]
1998 fn from_reflect_should_use_default_field_attributes() {
1999 #[derive(Reflect, Eq, PartialEq, Debug)]
2000 struct MyStruct {
2001 #[reflect(default)]
2004 foo: String,
2005
2006 #[reflect(ignore)]
2008 #[reflect(default = "get_bar_default")]
2009 bar: NotReflect,
2010
2011 #[reflect(ignore, default = "get_bar_default")]
2013 baz: NotReflect,
2014 }
2015
2016 #[derive(Eq, PartialEq, Debug)]
2017 struct NotReflect(usize);
2018
2019 fn get_bar_default() -> NotReflect {
2020 NotReflect(123)
2021 }
2022
2023 let expected = MyStruct {
2024 foo: String::default(),
2025 bar: NotReflect(123),
2026 baz: NotReflect(123),
2027 };
2028
2029 let dyn_struct = DynamicStruct::default();
2030 let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
2031
2032 assert_eq!(Some(expected), my_struct);
2033 }
2034
2035 #[test]
2036 fn from_reflect_should_use_default_variant_field_attributes() {
2037 #[derive(Reflect, Eq, PartialEq, Debug)]
2038 enum MyEnum {
2039 Foo(#[reflect(default)] String),
2040 Bar {
2041 #[reflect(default = "get_baz_default")]
2042 #[reflect(ignore)]
2043 baz: usize,
2044 },
2045 }
2046
2047 fn get_baz_default() -> usize {
2048 123
2049 }
2050
2051 let expected = MyEnum::Foo(String::default());
2052
2053 let dyn_enum = DynamicEnum::new("Foo", DynamicTuple::default());
2054 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
2055
2056 assert_eq!(Some(expected), my_enum);
2057
2058 let expected = MyEnum::Bar {
2059 baz: get_baz_default(),
2060 };
2061
2062 let dyn_enum = DynamicEnum::new("Bar", DynamicStruct::default());
2063 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
2064
2065 assert_eq!(Some(expected), my_enum);
2066 }
2067
2068 #[test]
2069 fn from_reflect_should_use_default_container_attribute() {
2070 #[derive(Reflect, Eq, PartialEq, Debug)]
2071 #[reflect(Default)]
2072 struct MyStruct {
2073 foo: String,
2074 #[reflect(ignore)]
2075 bar: usize,
2076 }
2077
2078 impl Default for MyStruct {
2079 fn default() -> Self {
2080 Self {
2081 foo: String::from("Hello"),
2082 bar: 123,
2083 }
2084 }
2085 }
2086
2087 let expected = MyStruct {
2088 foo: String::from("Hello"),
2089 bar: 123,
2090 };
2091
2092 let dyn_struct = DynamicStruct::default();
2093 let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
2094
2095 assert_eq!(Some(expected), my_struct);
2096 }
2097
2098 #[test]
2099 fn reflect_complex_patch() {
2100 #[derive(Reflect, Eq, PartialEq, Debug)]
2101 #[reflect(PartialEq)]
2102 struct Foo {
2103 a: u32,
2104 #[reflect(ignore)]
2105 _b: u32,
2106 c: Vec<isize>,
2107 d: HashMap<usize, i8>,
2108 e: Bar,
2109 f: (i32, Vec<isize>, Bar),
2110 g: Vec<(Baz, HashMap<usize, Bar>)>,
2111 h: [u32; 2],
2112 }
2113
2114 #[derive(Reflect, Eq, PartialEq, Clone, Debug)]
2115 #[reflect(PartialEq)]
2116 struct Bar {
2117 x: u32,
2118 }
2119
2120 #[derive(Reflect, Eq, PartialEq, Debug)]
2121 struct Baz(String);
2122
2123 let mut hash_map = <HashMap<_, _>>::default();
2124 hash_map.insert(1, 1);
2125 hash_map.insert(2, 2);
2126
2127 let mut hash_map_baz = <HashMap<_, _>>::default();
2128 hash_map_baz.insert(1, Bar { x: 0 });
2129
2130 let mut foo = Foo {
2131 a: 1,
2132 _b: 1,
2133 c: vec![1, 2],
2134 d: hash_map,
2135 e: Bar { x: 1 },
2136 f: (1, vec![1, 2], Bar { x: 1 }),
2137 g: vec![(Baz("string".to_string()), hash_map_baz)],
2138 h: [2; 2],
2139 };
2140
2141 let mut foo_patch = DynamicStruct::default();
2142 foo_patch.insert("a", 2u32);
2143 foo_patch.insert("b", 2u32); let mut list = DynamicList::default();
2146 list.push(3isize);
2147 list.push(4isize);
2148 list.push(5isize);
2149 foo_patch.insert("c", list.to_dynamic_list().unwrap());
2150
2151 let mut map = DynamicMap::default();
2152 map.insert(2usize, 3i8);
2153 map.insert(3usize, 4i8);
2154 foo_patch.insert("d", map);
2155
2156 let mut bar_patch = DynamicStruct::default();
2157 bar_patch.insert("x", 2u32);
2158 foo_patch.insert("e", bar_patch.to_dynamic_struct().unwrap());
2159
2160 let mut tuple = DynamicTuple::default();
2161 tuple.insert(2i32);
2162 tuple.insert(list);
2163 tuple.insert(bar_patch);
2164 foo_patch.insert("f", tuple);
2165
2166 let mut composite = DynamicList::default();
2167 composite.push({
2168 let mut tuple = DynamicTuple::default();
2169 tuple.insert({
2170 let mut tuple_struct = DynamicTupleStruct::default();
2171 tuple_struct.insert("new_string".to_string());
2172 tuple_struct
2173 });
2174 tuple.insert({
2175 let mut map = DynamicMap::default();
2176 map.insert(1usize, {
2177 let mut struct_ = DynamicStruct::default();
2178 struct_.insert("x", 7u32);
2179 struct_
2180 });
2181 map
2182 });
2183 tuple
2184 });
2185 foo_patch.insert("g", composite);
2186
2187 let array = DynamicArray::from_iter([2u32, 2u32]);
2188 foo_patch.insert("h", array);
2189
2190 foo.apply(&foo_patch);
2191
2192 let mut hash_map = <HashMap<_, _>>::default();
2193 hash_map.insert(2, 3);
2194 hash_map.insert(3, 4);
2195
2196 let mut hash_map_baz = <HashMap<_, _>>::default();
2197 hash_map_baz.insert(1, Bar { x: 7 });
2198
2199 let expected_foo = Foo {
2200 a: 2,
2201 _b: 1,
2202 c: vec![3, 4, 5],
2203 d: hash_map,
2204 e: Bar { x: 2 },
2205 f: (2, vec![3, 4, 5], Bar { x: 2 }),
2206 g: vec![(Baz("new_string".to_string()), hash_map_baz.clone())],
2207 h: [2; 2],
2208 };
2209
2210 assert_eq!(foo, expected_foo);
2211
2212 let new_foo = Foo::from_reflect(&foo_patch)
2213 .expect("error while creating a concrete type from a dynamic type");
2214
2215 let mut hash_map = <HashMap<_, _>>::default();
2216 hash_map.insert(2, 3);
2217 hash_map.insert(3, 4);
2218
2219 let expected_new_foo = Foo {
2220 a: 2,
2221 _b: 0,
2222 c: vec![3, 4, 5],
2223 d: hash_map,
2224 e: Bar { x: 2 },
2225 f: (2, vec![3, 4, 5], Bar { x: 2 }),
2226 g: vec![(Baz("new_string".to_string()), hash_map_baz)],
2227 h: [2; 2],
2228 };
2229
2230 assert_eq!(new_foo, expected_new_foo);
2231 }
2232
2233 #[test]
2234 fn should_auto_register_fields() {
2235 #[derive(Reflect)]
2236 struct Foo {
2237 bar: Bar,
2238 }
2239
2240 #[derive(Reflect)]
2241 enum Bar {
2242 Variant(Baz),
2243 }
2244
2245 #[derive(Reflect)]
2246 struct Baz(usize);
2247
2248 let mut registry = TypeRegistry::empty();
2250 registry.register::<Foo>();
2251
2252 assert!(
2253 registry.contains(TypeId::of::<Bar>()),
2254 "registry should contain auto-registered `Bar` from `Foo`"
2255 );
2256
2257 let mut registry = TypeRegistry::empty();
2259 registry.register::<Option<Foo>>();
2260
2261 assert!(
2262 registry.contains(TypeId::of::<Bar>()),
2263 "registry should contain auto-registered `Bar` from `Option<Foo>`"
2264 );
2265
2266 let mut registry = TypeRegistry::empty();
2268 registry.register::<(Foo, Foo)>();
2269
2270 assert!(
2271 registry.contains(TypeId::of::<Bar>()),
2272 "registry should contain auto-registered `Bar` from `(Foo, Foo)`"
2273 );
2274
2275 let mut registry = TypeRegistry::empty();
2277 registry.register::<[Foo; 3]>();
2278
2279 assert!(
2280 registry.contains(TypeId::of::<Bar>()),
2281 "registry should contain auto-registered `Bar` from `[Foo; 3]`"
2282 );
2283
2284 let mut registry = TypeRegistry::empty();
2286 registry.register::<Vec<Foo>>();
2287
2288 assert!(
2289 registry.contains(TypeId::of::<Bar>()),
2290 "registry should contain auto-registered `Bar` from `Vec<Foo>`"
2291 );
2292
2293 let mut registry = TypeRegistry::empty();
2295 registry.register::<HashMap<i32, Foo>>();
2296
2297 assert!(
2298 registry.contains(TypeId::of::<Bar>()),
2299 "registry should contain auto-registered `Bar` from `HashMap<i32, Foo>`"
2300 );
2301 }
2302
2303 #[test]
2304 fn should_allow_dynamic_fields() {
2305 #[derive(Reflect)]
2306 #[reflect(from_reflect = false)]
2307 struct MyStruct(
2308 DynamicEnum,
2309 DynamicTupleStruct,
2310 DynamicStruct,
2311 DynamicMap,
2312 DynamicList,
2313 DynamicArray,
2314 DynamicTuple,
2315 i32,
2316 );
2317
2318 assert_impl_all!(MyStruct: Reflect, GetTypeRegistration);
2319
2320 let mut registry = TypeRegistry::empty();
2321 registry.register::<MyStruct>();
2322
2323 assert_eq!(2, registry.iter().count());
2324 assert!(registry.contains(TypeId::of::<MyStruct>()));
2325 assert!(registry.contains(TypeId::of::<i32>()));
2326 }
2327
2328 #[test]
2329 fn should_not_auto_register_existing_types() {
2330 #[derive(Reflect)]
2331 struct Foo {
2332 bar: Bar,
2333 }
2334
2335 #[derive(Reflect, Default)]
2336 struct Bar(usize);
2337
2338 let mut registry = TypeRegistry::empty();
2339 registry.register::<Bar>();
2340 registry.register_type_data::<Bar, ReflectDefault>();
2341 registry.register::<Foo>();
2342
2343 assert!(
2344 registry
2345 .get_type_data::<ReflectDefault>(TypeId::of::<Bar>())
2346 .is_some(),
2347 "registry should contain existing registration for `Bar`"
2348 );
2349 }
2350
2351 #[test]
2352 fn reflect_serialize() {
2353 #[derive(Reflect)]
2354 struct Foo {
2355 a: u32,
2356 #[reflect(ignore)]
2357 _b: u32,
2358 c: Vec<isize>,
2359 d: HashMap<usize, i8>,
2360 e: Bar,
2361 f: String,
2362 g: (i32, Vec<isize>, Bar),
2363 h: [u32; 2],
2364 }
2365
2366 #[derive(Reflect, Serialize, Deserialize)]
2367 #[reflect(Serialize, Deserialize)]
2368 struct Bar {
2369 x: u32,
2370 }
2371
2372 let mut hash_map = <HashMap<_, _>>::default();
2373 hash_map.insert(1, 1);
2374 hash_map.insert(2, 2);
2375 let foo = Foo {
2376 a: 1,
2377 _b: 1,
2378 c: vec![1, 2],
2379 d: hash_map,
2380 e: Bar { x: 1 },
2381 f: "hi".to_string(),
2382 g: (1, vec![1, 2], Bar { x: 1 }),
2383 h: [2; 2],
2384 };
2385
2386 let mut registry = TypeRegistry::default();
2387 registry.register::<u32>();
2388 registry.register::<i8>();
2389 registry.register::<i32>();
2390 registry.register::<usize>();
2391 registry.register::<isize>();
2392 registry.register::<Foo>();
2393 registry.register::<Bar>();
2394 registry.register::<String>();
2395 registry.register::<Vec<isize>>();
2396 registry.register::<HashMap<usize, i8>>();
2397 registry.register::<(i32, Vec<isize>, Bar)>();
2398 registry.register::<[u32; 2]>();
2399
2400 let serializer = ReflectSerializer::new(&foo, ®istry);
2401 let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
2402
2403 let mut deserializer = Deserializer::from_str(&serialized).unwrap();
2404 let reflect_deserializer = ReflectDeserializer::new(®istry);
2405 let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
2406 let roundtrip_foo = Foo::from_reflect(value.as_partial_reflect()).unwrap();
2407
2408 assert!(foo.reflect_partial_eq(&roundtrip_foo).unwrap());
2409 }
2410
2411 #[test]
2412 fn reflect_downcast() {
2413 #[derive(Reflect, Clone, Debug, PartialEq)]
2414 struct Bar {
2415 y: u8,
2416 }
2417
2418 #[derive(Reflect, Clone, Debug, PartialEq)]
2419 struct Foo {
2420 x: i32,
2421 s: String,
2422 b: Bar,
2423 u: usize,
2424 t: ([f32; 3], String),
2425 v: Cow<'static, str>,
2426 w: Cow<'static, [u8]>,
2427 }
2428
2429 let foo = Foo {
2430 x: 123,
2431 s: "String".to_string(),
2432 b: Bar { y: 255 },
2433 u: 1111111111111,
2434 t: ([3.0, 2.0, 1.0], "Tuple String".to_string()),
2435 v: Cow::Owned("Cow String".to_string()),
2436 w: Cow::Owned(vec![1, 2, 3]),
2437 };
2438
2439 let foo2: Box<dyn Reflect> = Box::new(foo.clone());
2440
2441 assert_eq!(foo, *foo2.downcast::<Foo>().unwrap());
2442 }
2443
2444 #[test]
2445 fn should_drain_fields() {
2446 let array_value: Box<dyn Array> = Box::new([123_i32, 321_i32]);
2447 let fields = array_value.drain();
2448 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
2449 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
2450
2451 let mut list_value: Box<dyn List> = Box::new(vec![123_i32, 321_i32]);
2452 let fields = list_value.drain();
2453 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
2454 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
2455
2456 let tuple_value: Box<dyn Tuple> = Box::new((123_i32, 321_i32));
2457 let fields = tuple_value.drain();
2458 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
2459 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
2460
2461 let mut map_value: Box<dyn Map> =
2462 Box::new([(123_i32, 321_i32)].into_iter().collect::<HashMap<_, _>>());
2463 let fields = map_value.drain();
2464 assert!(fields[0].0.reflect_partial_eq(&123_i32).unwrap_or_default());
2465 assert!(fields[0].1.reflect_partial_eq(&321_i32).unwrap_or_default());
2466 }
2467
2468 #[test]
2469 fn reflect_take() {
2470 #[derive(Reflect, Debug, PartialEq)]
2471 #[reflect(PartialEq)]
2472 struct Bar {
2473 x: u32,
2474 }
2475
2476 let x: Box<dyn Reflect> = Box::new(Bar { x: 2 });
2477 let y = x.take::<Bar>().unwrap();
2478 assert_eq!(y, Bar { x: 2 });
2479 }
2480
2481 #[test]
2482 fn not_dynamic_names() {
2483 let list = Vec::<usize>::new();
2484 let dyn_list = list.to_dynamic_list().unwrap();
2485 assert_ne!(dyn_list.reflect_type_path(), Vec::<usize>::type_path());
2486
2487 let array = [b'0'; 4];
2488 let dyn_array = array.to_dynamic_array().unwrap();
2489 assert_ne!(dyn_array.reflect_type_path(), <[u8; 4]>::type_path());
2490
2491 let map = HashMap::<usize, String>::default();
2492 let dyn_map = map.to_dynamic_map().unwrap();
2493 assert_ne!(
2494 dyn_map.reflect_type_path(),
2495 HashMap::<usize, String>::type_path()
2496 );
2497
2498 let tuple = (0usize, "1".to_string(), 2.0f32);
2499 let mut dyn_tuple = tuple.to_dynamic_tuple().unwrap();
2500 dyn_tuple.insert::<usize>(3);
2501 assert_ne!(
2502 dyn_tuple.reflect_type_path(),
2503 <(usize, String, f32, usize)>::type_path()
2504 );
2505
2506 #[derive(Reflect)]
2507 struct TestStruct {
2508 a: usize,
2509 }
2510 let struct_ = TestStruct { a: 0 };
2511 let dyn_struct = struct_.to_dynamic_struct().unwrap();
2512 assert_ne!(dyn_struct.reflect_type_path(), TestStruct::type_path());
2513
2514 #[derive(Reflect)]
2515 struct TestTupleStruct(usize);
2516 let tuple_struct = TestTupleStruct(0);
2517 let dyn_tuple_struct = tuple_struct.to_dynamic_tuple_struct().unwrap();
2518 assert_ne!(
2519 dyn_tuple_struct.reflect_type_path(),
2520 TestTupleStruct::type_path()
2521 );
2522 }
2523
2524 macro_rules! assert_type_paths {
2525 ($($ty:ty => $long:literal, $short:literal,)*) => {
2526 $(
2527 assert_eq!(<$ty as TypePath>::type_path(), $long);
2528 assert_eq!(<$ty as TypePath>::short_type_path(), $short);
2529 )*
2530 };
2531 }
2532
2533 #[test]
2534 fn reflect_type_path() {
2535 #[derive(TypePath)]
2536 struct Param;
2537
2538 #[derive(TypePath)]
2539 struct Derive;
2540
2541 #[derive(TypePath)]
2542 #[type_path = "my_alias"]
2543 struct DerivePath;
2544
2545 #[derive(TypePath)]
2546 #[type_path = "my_alias"]
2547 #[type_name = "MyDerivePathName"]
2548 struct DerivePathName;
2549
2550 #[derive(TypePath)]
2551 struct DeriveG<T>(PhantomData<T>);
2552
2553 #[derive(TypePath)]
2554 #[type_path = "my_alias"]
2555 struct DerivePathG<T, const N: usize>(PhantomData<T>);
2556
2557 #[derive(TypePath)]
2558 #[type_path = "my_alias"]
2559 #[type_name = "MyDerivePathNameG"]
2560 struct DerivePathNameG<T>(PhantomData<T>);
2561
2562 struct Macro;
2563 impl_type_path!((in my_alias) Macro);
2564
2565 struct MacroName;
2566 impl_type_path!((in my_alias as MyMacroName) MacroName);
2567
2568 struct MacroG<T, const N: usize>(PhantomData<T>);
2569 impl_type_path!((in my_alias) MacroG<T, const N: usize>);
2570
2571 struct MacroNameG<T>(PhantomData<T>);
2572 impl_type_path!((in my_alias as MyMacroNameG) MacroNameG<T>);
2573
2574 assert_type_paths! {
2575 Derive => "bevy_reflect::tests::Derive", "Derive",
2576 DerivePath => "my_alias::DerivePath", "DerivePath",
2577 DerivePathName => "my_alias::MyDerivePathName", "MyDerivePathName",
2578 DeriveG<Param> => "bevy_reflect::tests::DeriveG<bevy_reflect::tests::Param>", "DeriveG<Param>",
2579 DerivePathG<Param, 10> => "my_alias::DerivePathG<bevy_reflect::tests::Param, 10>", "DerivePathG<Param, 10>",
2580 DerivePathNameG<Param> => "my_alias::MyDerivePathNameG<bevy_reflect::tests::Param>", "MyDerivePathNameG<Param>",
2581 Macro => "my_alias::Macro", "Macro",
2582 MacroName => "my_alias::MyMacroName", "MyMacroName",
2583 MacroG<Param, 10> => "my_alias::MacroG<bevy_reflect::tests::Param, 10>", "MacroG<Param, 10>",
2584 MacroNameG<Param> => "my_alias::MyMacroNameG<bevy_reflect::tests::Param>", "MyMacroNameG<Param>",
2585 }
2586 }
2587
2588 #[test]
2589 fn std_type_paths() {
2590 #[derive(Clone)]
2591 struct Type;
2592
2593 impl TypePath for Type {
2594 fn type_path() -> &'static str {
2595 "Long"
2597 }
2598
2599 fn short_type_path() -> &'static str {
2600 "Short"
2601 }
2602 }
2603
2604 assert_type_paths! {
2605 u8 => "u8", "u8",
2606 Type => "Long", "Short",
2607 &Type => "&Long", "&Short",
2608 [Type] => "[Long]", "[Short]",
2609 &[Type] => "&[Long]", "&[Short]",
2610 [Type; 0] => "[Long; 0]", "[Short; 0]",
2611 [Type; 100] => "[Long; 100]", "[Short; 100]",
2612 () => "()", "()",
2613 (Type,) => "(Long,)", "(Short,)",
2614 (Type, Type) => "(Long, Long)", "(Short, Short)",
2615 (Type, Type, Type) => "(Long, Long, Long)", "(Short, Short, Short)",
2616 Cow<'static, Type> => "alloc::borrow::Cow<Long>", "Cow<Short>",
2617 }
2618 }
2619
2620 #[test]
2621 fn reflect_type_info() {
2622 let info = i32::type_info();
2624 assert_eq!(i32::type_path(), info.type_path());
2625 assert_eq!(TypeId::of::<i32>(), info.type_id());
2626
2627 assert_eq!(
2629 TypeId::of::<dyn Reflect>(),
2630 <dyn Reflect as Typed>::type_info().type_id()
2631 );
2632
2633 let value: &dyn Reflect = &123_i32;
2635 let info = value.reflect_type_info();
2636 assert!(info.is::<i32>());
2637
2638 #[derive(Reflect)]
2640 struct MyStruct {
2641 foo: i32,
2642 bar: usize,
2643 }
2644
2645 let info = MyStruct::type_info().as_struct().unwrap();
2646 assert!(info.is::<MyStruct>());
2647 assert_eq!(MyStruct::type_path(), info.type_path());
2648 assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2649 assert_eq!(TypeId::of::<i32>(), info.field("foo").unwrap().type_id());
2650 assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2651 assert!(info.field("foo").unwrap().is::<i32>());
2652 assert_eq!("foo", info.field("foo").unwrap().name());
2653 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2654
2655 let value: &dyn Reflect = &MyStruct { foo: 123, bar: 321 };
2656 let info = value.reflect_type_info();
2657 assert!(info.is::<MyStruct>());
2658
2659 #[derive(Reflect)]
2661 struct MyGenericStruct<T> {
2662 foo: T,
2663 bar: usize,
2664 }
2665
2666 let info = <MyGenericStruct<i32>>::type_info().as_struct().unwrap();
2667 assert!(info.is::<MyGenericStruct<i32>>());
2668 assert_eq!(MyGenericStruct::<i32>::type_path(), info.type_path());
2669 assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2670 assert_eq!("foo", info.field("foo").unwrap().name());
2671 assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2672 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2673
2674 let value: &dyn Reflect = &MyGenericStruct {
2675 foo: String::from("Hello!"),
2676 bar: 321,
2677 };
2678 let info = value.reflect_type_info();
2679 assert!(info.is::<MyGenericStruct<String>>());
2680
2681 #[derive(Reflect)]
2683 #[reflect(from_reflect = false)]
2684 struct MyDynamicStruct {
2685 foo: DynamicStruct,
2686 bar: usize,
2687 }
2688
2689 let info = MyDynamicStruct::type_info();
2690 if let TypeInfo::Struct(info) = info {
2691 assert!(info.is::<MyDynamicStruct>());
2692 assert_eq!(MyDynamicStruct::type_path(), info.type_path());
2693 assert_eq!(
2694 DynamicStruct::type_path(),
2695 info.field("foo").unwrap().type_path()
2696 );
2697 assert_eq!("foo", info.field("foo").unwrap().name());
2698 assert!(info.field("foo").unwrap().type_info().is_none());
2699 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2700 } else {
2701 panic!("Expected `TypeInfo::Struct`");
2702 }
2703
2704 let value: &dyn Reflect = &MyDynamicStruct {
2705 foo: DynamicStruct::default(),
2706 bar: 321,
2707 };
2708 let info = value.reflect_type_info();
2709 assert!(info.is::<MyDynamicStruct>());
2710
2711 #[derive(Reflect)]
2713 struct MyTupleStruct(usize, i32, MyStruct);
2714
2715 let info = MyTupleStruct::type_info().as_tuple_struct().unwrap();
2716
2717 assert!(info.is::<MyTupleStruct>());
2718 assert_eq!(MyTupleStruct::type_path(), info.type_path());
2719 assert_eq!(i32::type_path(), info.field_at(1).unwrap().type_path());
2720 assert!(info.field_at(1).unwrap().type_info().unwrap().is::<i32>());
2721 assert!(info.field_at(1).unwrap().is::<i32>());
2722
2723 type MyTuple = (u32, f32, String);
2725
2726 let info = MyTuple::type_info().as_tuple().unwrap();
2727
2728 assert!(info.is::<MyTuple>());
2729 assert_eq!(MyTuple::type_path(), info.type_path());
2730 assert_eq!(f32::type_path(), info.field_at(1).unwrap().type_path());
2731 assert!(info.field_at(1).unwrap().type_info().unwrap().is::<f32>());
2732
2733 let value: &dyn Reflect = &(123_u32, 1.23_f32, String::from("Hello!"));
2734 let info = value.reflect_type_info();
2735 assert!(info.is::<MyTuple>());
2736
2737 type MyList = Vec<usize>;
2739
2740 let info = MyList::type_info().as_list().unwrap();
2741
2742 assert!(info.is::<MyList>());
2743 assert!(info.item_ty().is::<usize>());
2744 assert!(info.item_info().unwrap().is::<usize>());
2745 assert_eq!(MyList::type_path(), info.type_path());
2746 assert_eq!(usize::type_path(), info.item_ty().path());
2747
2748 let value: &dyn Reflect = &vec![123_usize];
2749 let info = value.reflect_type_info();
2750 assert!(info.is::<MyList>());
2751
2752 #[cfg(feature = "smallvec")]
2754 {
2755 type MySmallVec = smallvec::SmallVec<[String; 2]>;
2756
2757 let info = MySmallVec::type_info().as_list().unwrap();
2758 assert!(info.is::<MySmallVec>());
2759 assert!(info.item_ty().is::<String>());
2760 assert!(info.item_info().unwrap().is::<String>());
2761 assert_eq!(MySmallVec::type_path(), info.type_path());
2762 assert_eq!(String::type_path(), info.item_ty().path());
2763
2764 let value: MySmallVec = smallvec::smallvec![String::default(); 2];
2765 let value: &dyn Reflect = &value;
2766 let info = value.reflect_type_info();
2767 assert!(info.is::<MySmallVec>());
2768 }
2769
2770 type MyArray = [usize; 3];
2772
2773 let info = MyArray::type_info().as_array().unwrap();
2774 assert!(info.is::<MyArray>());
2775 assert!(info.item_ty().is::<usize>());
2776 assert!(info.item_info().unwrap().is::<usize>());
2777 assert_eq!(MyArray::type_path(), info.type_path());
2778 assert_eq!(usize::type_path(), info.item_ty().path());
2779 assert_eq!(3, info.capacity());
2780
2781 let value: &dyn Reflect = &[1usize, 2usize, 3usize];
2782 let info = value.reflect_type_info();
2783 assert!(info.is::<MyArray>());
2784
2785 type MyCowStr = Cow<'static, str>;
2787
2788 let info = MyCowStr::type_info().as_opaque().unwrap();
2789
2790 assert!(info.is::<MyCowStr>());
2791 assert_eq!("alloc::borrow::Cow<str>", info.type_path());
2792
2793 let value: &dyn Reflect = &Cow::<'static, str>::Owned("Hello!".to_string());
2794 let info = value.reflect_type_info();
2795 assert!(info.is::<MyCowStr>());
2796
2797 type MyCowSlice = Cow<'static, [u8]>;
2799
2800 let info = MyCowSlice::type_info().as_list().unwrap();
2801
2802 assert!(info.is::<MyCowSlice>());
2803 assert!(info.item_ty().is::<u8>());
2804 assert!(info.item_info().unwrap().is::<u8>());
2805 assert_eq!("alloc::borrow::Cow<[u8]>", info.type_path());
2806 assert_eq!("u8", info.item_ty().path());
2807
2808 let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]);
2809 let info = value.reflect_type_info();
2810 assert!(info.is::<MyCowSlice>());
2811
2812 type MyMap = HashMap<usize, f32>;
2814
2815 let info = MyMap::type_info().as_map().unwrap();
2816
2817 assert!(info.is::<MyMap>());
2818 assert!(info.key_ty().is::<usize>());
2819 assert!(info.value_ty().is::<f32>());
2820 assert!(info.key_info().unwrap().is::<usize>());
2821 assert!(info.value_info().unwrap().is::<f32>());
2822 assert_eq!(MyMap::type_path(), info.type_path());
2823 assert_eq!(usize::type_path(), info.key_ty().path());
2824 assert_eq!(f32::type_path(), info.value_ty().path());
2825
2826 let value: &dyn Reflect = &MyMap::default();
2827 let info = value.reflect_type_info();
2828 assert!(info.is::<MyMap>());
2829
2830 #[cfg(feature = "indexmap")]
2832 {
2833 use std::hash::RandomState;
2834
2835 type MyIndexMap = indexmap::IndexMap<String, u32, RandomState>;
2836
2837 let info = MyIndexMap::type_info().as_map().unwrap();
2838 assert!(info.is::<MyIndexMap>());
2839 assert_eq!(MyIndexMap::type_path(), info.type_path());
2840
2841 assert!(info.key_ty().is::<String>());
2842 assert!(info.key_info().unwrap().is::<String>());
2843 assert_eq!(String::type_path(), info.key_ty().path());
2844
2845 assert!(info.value_ty().is::<u32>());
2846 assert!(info.value_info().unwrap().is::<u32>());
2847 assert_eq!(u32::type_path(), info.value_ty().path());
2848
2849 let value: MyIndexMap = MyIndexMap::with_capacity_and_hasher(10, RandomState::new());
2850 let value: &dyn Reflect = &value;
2851 let info = value.reflect_type_info();
2852 assert!(info.is::<MyIndexMap>());
2853 }
2854
2855 type MyValue = String;
2857
2858 let info = MyValue::type_info().as_opaque().unwrap();
2859
2860 assert!(info.is::<MyValue>());
2861 assert_eq!(MyValue::type_path(), info.type_path());
2862
2863 let value: &dyn Reflect = &String::from("Hello!");
2864 let info = value.reflect_type_info();
2865 assert!(info.is::<MyValue>());
2866 }
2867
2868 #[test]
2869 fn get_represented_kind_info() {
2870 #[derive(Reflect)]
2871 struct SomeStruct;
2872
2873 #[derive(Reflect)]
2874 struct SomeTupleStruct(f32);
2875
2876 #[derive(Reflect)]
2877 enum SomeEnum {
2878 Foo,
2879 Bar,
2880 }
2881
2882 let dyn_struct: &dyn Struct = &SomeStruct;
2883 let _: &StructInfo = dyn_struct.get_represented_struct_info().unwrap();
2884
2885 let dyn_map: &dyn Map = &HashMap::<(), ()>::default();
2886 let _: &MapInfo = dyn_map.get_represented_map_info().unwrap();
2887
2888 let dyn_array: &dyn Array = &[1, 2, 3];
2889 let _: &ArrayInfo = dyn_array.get_represented_array_info().unwrap();
2890
2891 let dyn_list: &dyn List = &vec![1, 2, 3];
2892 let _: &ListInfo = dyn_list.get_represented_list_info().unwrap();
2893
2894 let dyn_tuple_struct: &dyn TupleStruct = &SomeTupleStruct(5.0);
2895 let _: &TupleStructInfo = dyn_tuple_struct
2896 .get_represented_tuple_struct_info()
2897 .unwrap();
2898
2899 let dyn_enum: &dyn Enum = &SomeEnum::Foo;
2900 let _: &EnumInfo = dyn_enum.get_represented_enum_info().unwrap();
2901 }
2902
2903 #[test]
2904 fn should_permit_higher_ranked_lifetimes() {
2905 #[derive(Reflect)]
2906 #[reflect(from_reflect = false)]
2907 struct TestStruct {
2908 #[reflect(ignore)]
2909 _hrl: for<'a> fn(&'a str) -> &'a str,
2910 }
2911
2912 impl Default for TestStruct {
2913 fn default() -> Self {
2914 TestStruct {
2915 _hrl: |input| input,
2916 }
2917 }
2918 }
2919
2920 fn get_type_registration<T: GetTypeRegistration>() {}
2921 get_type_registration::<TestStruct>();
2922 }
2923
2924 #[test]
2925 fn should_permit_valid_represented_type_for_dynamic() {
2926 let type_info = <[i32; 2] as Typed>::type_info();
2927 let mut dynamic_array = [123; 2].to_dynamic_array().unwrap();
2928 dynamic_array.set_represented_type(Some(type_info));
2929 }
2930
2931 #[test]
2932 #[should_panic(expected = "expected TypeInfo::Array but received")]
2933 fn should_prohibit_invalid_represented_type_for_dynamic() {
2934 let type_info = <(i32, i32) as Typed>::type_info();
2935 let mut dynamic_array = [123; 2].to_dynamic_array().unwrap();
2936 dynamic_array.set_represented_type(Some(type_info));
2937 }
2938
2939 #[cfg(feature = "reflect_documentation")]
2940 mod docstrings {
2941 use super::*;
2942
2943 #[test]
2944 fn should_not_contain_docs() {
2945 #[derive(Reflect)]
2948 struct SomeStruct;
2949
2950 let info = <SomeStruct as Typed>::type_info();
2951 assert_eq!(None, info.docs());
2952
2953 #[derive(Reflect)]
2956 struct SomeOtherStruct;
2957
2958 let info = <SomeOtherStruct as Typed>::type_info();
2959 assert_eq!(None, info.docs());
2960 }
2961
2962 #[test]
2963 fn should_contain_docs() {
2964 #[derive(Reflect)]
2972 struct SomeStruct;
2973
2974 let info = <SomeStruct as Typed>::type_info();
2975 assert_eq!(
2976 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 ```"),
2977 info.docs()
2978 );
2979
2980 #[doc = "The compiler automatically converts `///`-style comments into `#[doc]` attributes."]
2981 #[doc = "Of course, you _could_ use the attribute directly if you wanted to."]
2982 #[doc = "Both will be reflected."]
2983 #[derive(Reflect)]
2984 struct SomeOtherStruct;
2985
2986 let info = <SomeOtherStruct as Typed>::type_info();
2987 assert_eq!(
2988 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."),
2989 info.docs()
2990 );
2991
2992 #[derive(Reflect)]
2994 struct SomeTupleStruct(usize);
2995
2996 let info = <SomeTupleStruct as Typed>::type_info();
2997 assert_eq!(Some(" Some tuple struct."), info.docs());
2998
2999 #[derive(Reflect)]
3001 enum SomeEnum {
3002 Foo,
3003 }
3004
3005 let info = <SomeEnum as Typed>::type_info();
3006 assert_eq!(Some(" Some enum."), info.docs());
3007
3008 #[derive(Clone)]
3009 struct SomePrimitive;
3010 impl_reflect_opaque!(
3011 (in bevy_reflect::tests) SomePrimitive
3013 );
3014
3015 let info = <SomePrimitive as Typed>::type_info();
3016 assert_eq!(
3017 Some(" Some primitive for which we have attributed custom documentation."),
3018 info.docs()
3019 );
3020 }
3021
3022 #[test]
3023 fn fields_should_contain_docs() {
3024 #[derive(Reflect)]
3025 struct SomeStruct {
3026 name: String,
3028 index: usize,
3030 data: Vec<i32>,
3032 }
3033
3034 let info = <SomeStruct as Typed>::type_info().as_struct().unwrap();
3035
3036 let mut fields = info.iter();
3037 assert_eq!(Some(" The name"), fields.next().unwrap().docs());
3038 assert_eq!(Some(" The index"), fields.next().unwrap().docs());
3039 assert_eq!(None, fields.next().unwrap().docs());
3040 }
3041
3042 #[test]
3043 fn variants_should_contain_docs() {
3044 #[derive(Reflect)]
3045 enum SomeEnum {
3046 Nothing,
3048 A(
3050 usize,
3052 ),
3053 B {
3055 name: String,
3057 },
3058 }
3059
3060 let info = <SomeEnum as Typed>::type_info().as_enum().unwrap();
3061
3062 let mut variants = info.iter();
3063 assert_eq!(None, variants.next().unwrap().docs());
3064
3065 let variant = variants.next().unwrap().as_tuple_variant().unwrap();
3066 assert_eq!(Some(" Option A"), variant.docs());
3067 let field = variant.field_at(0).unwrap();
3068 assert_eq!(Some(" Index"), field.docs());
3069
3070 let variant = variants.next().unwrap().as_struct_variant().unwrap();
3071 assert_eq!(Some(" Option B"), variant.docs());
3072 let field = variant.field_at(0).unwrap();
3073 assert_eq!(Some(" Name"), field.docs());
3074 }
3075 }
3076
3077 #[test]
3078 fn into_reflect() {
3079 trait TestTrait: Reflect {}
3080
3081 #[derive(Reflect)]
3082 struct TestStruct;
3083
3084 impl TestTrait for TestStruct {}
3085
3086 let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
3087
3088 let _ = trait_object.into_reflect();
3090 }
3091
3092 #[test]
3093 fn as_reflect() {
3094 trait TestTrait: Reflect {}
3095
3096 #[derive(Reflect)]
3097 struct TestStruct;
3098
3099 impl TestTrait for TestStruct {}
3100
3101 let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
3102
3103 let _ = trait_object.as_reflect();
3105 }
3106
3107 #[test]
3108 fn should_reflect_debug() {
3109 #[derive(Reflect)]
3110 struct Test {
3111 value: usize,
3112 list: Vec<String>,
3113 array: [f32; 3],
3114 map: HashMap<i32, f32>,
3115 a_struct: SomeStruct,
3116 a_tuple_struct: SomeTupleStruct,
3117 enum_unit: SomeEnum,
3118 enum_tuple: SomeEnum,
3119 enum_struct: SomeEnum,
3120 custom: CustomDebug,
3121 #[reflect(ignore)]
3122 #[expect(dead_code, reason = "This value is intended to not be reflected.")]
3123 ignored: isize,
3124 }
3125
3126 #[derive(Reflect)]
3127 struct SomeStruct {
3128 foo: String,
3129 }
3130
3131 #[derive(Reflect)]
3132 enum SomeEnum {
3133 A,
3134 B(usize),
3135 C { value: i32 },
3136 }
3137
3138 #[derive(Reflect)]
3139 struct SomeTupleStruct(String);
3140
3141 #[derive(Reflect)]
3142 #[reflect(Debug)]
3143 struct CustomDebug;
3144 impl Debug for CustomDebug {
3145 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
3146 f.write_str("Cool debug!")
3147 }
3148 }
3149
3150 let mut map = <HashMap<_, _>>::default();
3151 map.insert(123, 1.23);
3152
3153 let test = Test {
3154 value: 123,
3155 list: vec![String::from("A"), String::from("B"), String::from("C")],
3156 array: [1.0, 2.0, 3.0],
3157 map,
3158 a_struct: SomeStruct {
3159 foo: String::from("A Struct!"),
3160 },
3161 a_tuple_struct: SomeTupleStruct(String::from("A Tuple Struct!")),
3162 enum_unit: SomeEnum::A,
3163 enum_tuple: SomeEnum::B(123),
3164 enum_struct: SomeEnum::C { value: 321 },
3165 custom: CustomDebug,
3166 ignored: 321,
3167 };
3168
3169 let reflected: &dyn Reflect = &test;
3170 let expected = r#"
3171bevy_reflect::tests::Test {
3172 value: 123,
3173 list: [
3174 "A",
3175 "B",
3176 "C",
3177 ],
3178 array: [
3179 1.0,
3180 2.0,
3181 3.0,
3182 ],
3183 map: {
3184 123: 1.23,
3185 },
3186 a_struct: bevy_reflect::tests::SomeStruct {
3187 foo: "A Struct!",
3188 },
3189 a_tuple_struct: bevy_reflect::tests::SomeTupleStruct(
3190 "A Tuple Struct!",
3191 ),
3192 enum_unit: A,
3193 enum_tuple: B(
3194 123,
3195 ),
3196 enum_struct: C {
3197 value: 321,
3198 },
3199 custom: Cool debug!,
3200}"#;
3201
3202 assert_eq!(expected, format!("\n{reflected:#?}"));
3203 }
3204
3205 #[test]
3206 fn multiple_reflect_lists() {
3207 #[derive(Hash, PartialEq, Reflect)]
3208 #[reflect(Debug, Hash)]
3209 #[reflect(PartialEq)]
3210 struct Foo(i32);
3211
3212 impl Debug for Foo {
3213 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
3214 write!(f, "Foo")
3215 }
3216 }
3217
3218 let foo = Foo(123);
3219 let foo: &dyn PartialReflect = &foo;
3220
3221 assert!(foo.reflect_hash().is_some());
3222 assert_eq!(Some(true), foo.reflect_partial_eq(foo));
3223 assert_eq!("Foo".to_string(), format!("{foo:?}"));
3224 }
3225
3226 #[test]
3227 fn custom_debug_function() {
3228 #[derive(Reflect)]
3229 #[reflect(Debug(custom_debug))]
3230 struct Foo {
3231 a: u32,
3232 }
3233
3234 fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> core::fmt::Result {
3235 write!(f, "123")
3236 }
3237
3238 let foo = Foo { a: 1 };
3239 let foo: &dyn Reflect = &foo;
3240
3241 assert_eq!("123", format!("{foo:?}"));
3242 }
3243
3244 #[test]
3245 fn should_allow_custom_where() {
3246 #[derive(Reflect)]
3247 #[reflect(where T: Default)]
3248 struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
3249
3250 #[derive(Default, TypePath)]
3251 struct Bar;
3252
3253 #[derive(TypePath)]
3254 struct Baz;
3255
3256 assert_impl_all!(Foo<Bar>: Reflect);
3257 assert_not_impl_all!(Foo<Baz>: Reflect);
3258 }
3259
3260 #[test]
3261 fn should_allow_empty_custom_where() {
3262 #[derive(Reflect)]
3263 #[reflect(where)]
3264 struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
3265
3266 #[derive(TypePath)]
3267 struct Bar;
3268
3269 assert_impl_all!(Foo<Bar>: Reflect);
3270 }
3271
3272 #[test]
3273 fn should_allow_multiple_custom_where() {
3274 #[derive(Reflect)]
3275 #[reflect(where T: Default)]
3276 #[reflect(where U: core::ops::Add<T>)]
3277 struct Foo<T, U>(T, U);
3278
3279 #[allow(
3280 clippy::allow_attributes,
3281 dead_code,
3282 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3283 )]
3284 #[derive(Reflect)]
3285 struct Baz {
3286 a: Foo<i32, i32>,
3287 b: Foo<u32, u32>,
3288 }
3289
3290 assert_impl_all!(Foo<i32, i32>: Reflect);
3291 assert_not_impl_all!(Foo<i32, usize>: Reflect);
3292 }
3293
3294 #[test]
3295 fn should_allow_custom_where_with_assoc_type() {
3296 trait Trait {
3297 type Assoc;
3298 }
3299
3300 #[derive(Reflect)]
3302 #[reflect(where T::Assoc: core::fmt::Display)]
3303 struct Foo<T: Trait>(T::Assoc);
3304
3305 #[derive(TypePath)]
3306 struct Bar;
3307
3308 impl Trait for Bar {
3309 type Assoc = usize;
3310 }
3311
3312 #[derive(TypePath)]
3313 struct Baz;
3314
3315 impl Trait for Baz {
3316 type Assoc = (f32, f32);
3317 }
3318
3319 assert_impl_all!(Foo<Bar>: Reflect);
3320 assert_not_impl_all!(Foo<Baz>: Reflect);
3321 }
3322
3323 #[test]
3324 fn should_allow_empty_enums() {
3325 #[derive(Reflect)]
3326 enum Empty {}
3327
3328 assert_impl_all!(Empty: Reflect);
3329 }
3330
3331 #[test]
3332 fn recursive_typed_storage_does_not_hang() {
3333 #[derive(Reflect)]
3334 struct Recurse<T>(T);
3335
3336 let _ = <Recurse<Recurse<()>> as Typed>::type_info();
3337 let _ = <Recurse<Recurse<()>> as TypePath>::type_path();
3338
3339 #[derive(Reflect)]
3340 #[reflect(no_field_bounds)]
3341 struct SelfRecurse {
3342 recurse: Vec<SelfRecurse>,
3343 }
3344
3345 let _ = <SelfRecurse as Typed>::type_info();
3346 let _ = <SelfRecurse as TypePath>::type_path();
3347
3348 #[derive(Reflect)]
3349 #[reflect(no_field_bounds)]
3350 enum RecurseA {
3351 Recurse(RecurseB),
3352 }
3353
3354 #[derive(Reflect)]
3355 struct RecurseB {
3357 vector: Vec<RecurseA>,
3358 }
3359
3360 let _ = <RecurseA as Typed>::type_info();
3361 let _ = <RecurseA as TypePath>::type_path();
3362 let _ = <RecurseB as Typed>::type_info();
3363 let _ = <RecurseB as TypePath>::type_path();
3364 }
3365
3366 #[test]
3367 fn recursive_registration_does_not_hang() {
3368 #[derive(Reflect)]
3369 struct Recurse<T>(T);
3370
3371 let mut registry = TypeRegistry::empty();
3372
3373 registry.register::<Recurse<Recurse<()>>>();
3374
3375 #[derive(Reflect)]
3376 #[reflect(no_field_bounds)]
3377 struct SelfRecurse {
3378 recurse: Vec<SelfRecurse>,
3379 }
3380
3381 registry.register::<SelfRecurse>();
3382
3383 #[derive(Reflect)]
3384 #[reflect(no_field_bounds)]
3385 enum RecurseA {
3386 Recurse(RecurseB),
3387 }
3388
3389 #[derive(Reflect)]
3390 struct RecurseB {
3391 vector: Vec<RecurseA>,
3392 }
3393
3394 registry.register::<RecurseA>();
3395 assert!(registry.contains(TypeId::of::<RecurseA>()));
3396 assert!(registry.contains(TypeId::of::<RecurseB>()));
3397 }
3398
3399 #[test]
3400 fn can_opt_out_type_path() {
3401 #[derive(Reflect)]
3402 #[reflect(type_path = false)]
3403 struct Foo<T> {
3404 #[reflect(ignore)]
3405 _marker: PhantomData<T>,
3406 }
3407
3408 struct NotTypePath;
3409
3410 impl<T: 'static> TypePath for Foo<T> {
3411 fn type_path() -> &'static str {
3412 core::any::type_name::<Self>()
3413 }
3414
3415 fn short_type_path() -> &'static str {
3416 static CELL: GenericTypePathCell = GenericTypePathCell::new();
3417 CELL.get_or_insert::<Self, _>(|| ShortName::of::<Self>().to_string())
3418 }
3419
3420 fn type_ident() -> Option<&'static str> {
3421 Some("Foo")
3422 }
3423
3424 fn crate_name() -> Option<&'static str> {
3425 Some("bevy_reflect")
3426 }
3427
3428 fn module_path() -> Option<&'static str> {
3429 Some("bevy_reflect::tests")
3430 }
3431 }
3432
3433 let path = <Foo<NotTypePath> as TypePath>::type_path();
3435 assert_eq!("bevy_reflect::tests::can_opt_out_type_path::Foo<bevy_reflect::tests::can_opt_out_type_path::NotTypePath>", path);
3436
3437 let mut registry = TypeRegistry::default();
3439 registry.register::<Foo<NotTypePath>>();
3440
3441 let registration = registry.get(TypeId::of::<Foo<NotTypePath>>()).unwrap();
3442 assert_eq!(
3443 "Foo<NotTypePath>",
3444 registration.type_info().type_path_table().short_path()
3445 );
3446 }
3447
3448 #[test]
3449 fn dynamic_types_debug_format() {
3450 #[derive(Debug, Reflect)]
3451 struct TestTupleStruct(u32);
3452
3453 #[derive(Debug, Reflect)]
3454 enum TestEnum {
3455 A(u32),
3456 B,
3457 }
3458
3459 #[derive(Debug, Reflect)]
3460 struct TestStruct {
3462 tuple: (u32, u32),
3464 tuple_struct: TestTupleStruct,
3466 list: Vec<u32>,
3468 array: [u32; 3],
3470 e: TestEnum,
3472 map: HashMap<u32, u32>,
3474 value: u32,
3476 }
3477 let mut map = <HashMap<_, _>>::default();
3478 map.insert(9, 10);
3479 let mut test_struct: DynamicStruct = TestStruct {
3480 tuple: (0, 1),
3481 list: vec![2, 3, 4],
3482 array: [5, 6, 7],
3483 tuple_struct: TestTupleStruct(8),
3484 e: TestEnum::A(11),
3485 map,
3486 value: 12,
3487 }
3488 .to_dynamic_struct()
3489 .unwrap();
3490
3491 let mut test_unknown_struct = DynamicStruct::default();
3493 test_unknown_struct.insert("a", 13);
3494 test_struct.insert("unknown_struct", test_unknown_struct);
3495 let mut test_unknown_tuple_struct = DynamicTupleStruct::default();
3497 test_unknown_tuple_struct.insert(14);
3498 test_struct.insert("unknown_tuplestruct", test_unknown_tuple_struct);
3499 assert_eq!(
3500 format!("{test_struct:?}"),
3501 "DynamicStruct(bevy_reflect::tests::TestStruct { \
3502 tuple: DynamicTuple((0, 1)), \
3503 tuple_struct: DynamicTupleStruct(bevy_reflect::tests::TestTupleStruct(8)), \
3504 list: DynamicList([2, 3, 4]), \
3505 array: DynamicArray([5, 6, 7]), \
3506 e: DynamicEnum(A(11)), \
3507 map: DynamicMap({9: 10}), \
3508 value: 12, \
3509 unknown_struct: DynamicStruct(_ { a: 13 }), \
3510 unknown_tuplestruct: DynamicTupleStruct(_(14)) \
3511 })"
3512 );
3513 }
3514
3515 #[test]
3516 fn assert_impl_reflect_macro_on_all() {
3517 struct Struct {
3518 foo: (),
3519 }
3520 struct TupleStruct(());
3521 enum Enum {
3522 Foo { foo: () },
3523 Bar(()),
3524 }
3525
3526 impl_reflect!(
3527 #[type_path = "my_crate::foo"]
3528 struct Struct {
3529 foo: (),
3530 }
3531 );
3532
3533 impl_reflect!(
3534 #[type_path = "my_crate::foo"]
3535 struct TupleStruct(());
3536 );
3537
3538 impl_reflect!(
3539 #[type_path = "my_crate::foo"]
3540 enum Enum {
3541 Foo { foo: () },
3542 Bar(()),
3543 }
3544 );
3545
3546 assert_impl_all!(Struct: Reflect);
3547 assert_impl_all!(TupleStruct: Reflect);
3548 assert_impl_all!(Enum: Reflect);
3549 }
3550
3551 #[test]
3552 fn should_reflect_remote_type() {
3553 mod external_crate {
3554 use alloc::string::String;
3555
3556 #[derive(Debug, Default)]
3557 pub struct TheirType {
3558 pub value: String,
3559 }
3560 }
3561
3562 #[reflect_remote(external_crate::TheirType)]
3564 #[derive(Debug, Default)]
3565 #[reflect(Debug, Default)]
3566 struct MyType {
3567 pub value: String,
3568 }
3569
3570 let mut patch = DynamicStruct::default();
3571 patch.set_represented_type(Some(MyType::type_info()));
3572 patch.insert("value", "Goodbye".to_string());
3573
3574 let mut data = MyType(external_crate::TheirType {
3575 value: "Hello".to_string(),
3576 });
3577
3578 assert_eq!("Hello", data.0.value);
3579 data.apply(&patch);
3580 assert_eq!("Goodbye", data.0.value);
3581
3582 #[derive(Reflect, Debug)]
3584 #[reflect(from_reflect = false)]
3585 struct ContainerStruct {
3586 #[reflect(remote = MyType)]
3587 their_type: external_crate::TheirType,
3588 }
3589
3590 let mut patch = DynamicStruct::default();
3591 patch.set_represented_type(Some(ContainerStruct::type_info()));
3592 patch.insert(
3593 "their_type",
3594 MyType(external_crate::TheirType {
3595 value: "Goodbye".to_string(),
3596 }),
3597 );
3598
3599 let mut data = ContainerStruct {
3600 their_type: external_crate::TheirType {
3601 value: "Hello".to_string(),
3602 },
3603 };
3604
3605 assert_eq!("Hello", data.their_type.value);
3606 data.apply(&patch);
3607 assert_eq!("Goodbye", data.their_type.value);
3608
3609 #[derive(Reflect, Debug)]
3611 struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3612
3613 let mut patch = DynamicTupleStruct::default();
3614 patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3615 patch.insert(MyType(external_crate::TheirType {
3616 value: "Goodbye".to_string(),
3617 }));
3618
3619 let mut data = ContainerTupleStruct(external_crate::TheirType {
3620 value: "Hello".to_string(),
3621 });
3622
3623 assert_eq!("Hello", data.0.value);
3624 data.apply(&patch);
3625 assert_eq!("Goodbye", data.0.value);
3626 }
3627
3628 #[test]
3629 fn from_reflect_uses_remote_conversion() {
3630 #[derive(Reflect)]
3631 struct BadWrapper(u8);
3632
3633 impl ReflectRemote for BadWrapper {
3634 type Remote = bool;
3635
3636 fn as_remote(&self) -> &Self::Remote {
3637 panic!("not used by this test")
3638 }
3639
3640 fn as_remote_mut(&mut self) -> &mut Self::Remote {
3641 panic!("not used by this test")
3642 }
3643
3644 fn into_remote(self) -> Self::Remote {
3645 false
3646 }
3647
3648 fn as_wrapper(_: &Self::Remote) -> &Self {
3649 panic!("not used by this test")
3650 }
3651
3652 fn as_wrapper_mut(_: &mut Self::Remote) -> &mut Self {
3653 panic!("not used by this test")
3654 }
3655
3656 fn into_wrapper(_: Self::Remote) -> Self {
3657 panic!("not used by this test")
3658 }
3659 }
3660
3661 #[derive(Reflect)]
3662 struct Container {
3663 #[reflect(remote = BadWrapper)]
3664 value: bool,
3665 }
3666
3667 let mut reflected = DynamicStruct::default();
3668 reflected.insert("value", BadWrapper(2));
3669
3670 let container = Container::from_reflect(&reflected).unwrap();
3671 assert!(!container.value);
3672 }
3673
3674 #[test]
3675 fn should_reflect_remote_value_type() {
3676 mod external_crate {
3677 use alloc::string::String;
3678
3679 #[derive(Clone, Debug, Default)]
3680 pub struct TheirType {
3681 pub value: String,
3682 }
3683 }
3684
3685 #[reflect_remote(external_crate::TheirType)]
3687 #[derive(Clone, Debug, Default)]
3688 #[reflect(opaque)]
3689 #[reflect(Debug, Default)]
3690 struct MyType {
3691 pub value: String,
3692 }
3693
3694 let mut data = MyType(external_crate::TheirType {
3695 value: "Hello".to_string(),
3696 });
3697
3698 let patch = MyType(external_crate::TheirType {
3699 value: "Goodbye".to_string(),
3700 });
3701
3702 assert_eq!("Hello", data.0.value);
3703 data.apply(&patch);
3704 assert_eq!("Goodbye", data.0.value);
3705
3706 #[derive(Reflect, Debug)]
3708 #[reflect(from_reflect = false)]
3709 struct ContainerStruct {
3710 #[reflect(remote = MyType)]
3711 their_type: external_crate::TheirType,
3712 }
3713
3714 let mut patch = DynamicStruct::default();
3715 patch.set_represented_type(Some(ContainerStruct::type_info()));
3716 patch.insert(
3717 "their_type",
3718 MyType(external_crate::TheirType {
3719 value: "Goodbye".to_string(),
3720 }),
3721 );
3722
3723 let mut data = ContainerStruct {
3724 their_type: external_crate::TheirType {
3725 value: "Hello".to_string(),
3726 },
3727 };
3728
3729 assert_eq!("Hello", data.their_type.value);
3730 data.apply(&patch);
3731 assert_eq!("Goodbye", data.their_type.value);
3732
3733 #[derive(Reflect, Debug)]
3735 struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3736
3737 let mut patch = DynamicTupleStruct::default();
3738 patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3739 patch.insert(MyType(external_crate::TheirType {
3740 value: "Goodbye".to_string(),
3741 }));
3742
3743 let mut data = ContainerTupleStruct(external_crate::TheirType {
3744 value: "Hello".to_string(),
3745 });
3746
3747 assert_eq!("Hello", data.0.value);
3748 data.apply(&patch);
3749 assert_eq!("Goodbye", data.0.value);
3750 }
3751
3752 #[test]
3753 fn should_reflect_remote_type_from_module() {
3754 mod wrapper {
3755 use super::*;
3756
3757 pub mod external_crate {
3762 use alloc::string::String;
3763
3764 #[allow(
3765 clippy::allow_attributes,
3766 dead_code,
3767 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3768 )]
3769 pub struct TheirType {
3770 pub value: String,
3771 }
3772 }
3773
3774 #[reflect_remote(external_crate::TheirType)]
3775 pub struct MyType {
3776 pub value: String,
3777 }
3778 }
3779
3780 #[allow(
3781 clippy::allow_attributes,
3782 dead_code,
3783 reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3784 )]
3785 #[derive(Reflect)]
3786 struct ContainerStruct {
3787 #[reflect(remote = wrapper::MyType)]
3788 their_type: wrapper::external_crate::TheirType,
3789 }
3790 }
3791
3792 #[test]
3793 fn should_reflect_remote_enum() {
3794 mod external_crate {
3795 use alloc::string::String;
3796
3797 #[derive(Debug, PartialEq, Eq)]
3798 pub enum TheirType {
3799 Unit,
3800 Tuple(usize),
3801 Struct { value: String },
3802 }
3803 }
3804
3805 #[reflect_remote(external_crate::TheirType)]
3807 #[derive(Debug)]
3808 #[reflect(Debug)]
3809 enum MyType {
3810 Unit,
3811 Tuple(usize),
3812 Struct { value: String },
3813 }
3814
3815 let mut patch =
3816 DynamicEnum::try_from(MyType(external_crate::TheirType::Tuple(123))).unwrap();
3817
3818 let mut data = MyType(external_crate::TheirType::Unit);
3819
3820 assert_eq!(external_crate::TheirType::Unit, data.0);
3821 data.apply(&patch);
3822 assert_eq!(external_crate::TheirType::Tuple(123), data.0);
3823
3824 patch = DynamicEnum::try_from(MyType(external_crate::TheirType::Struct {
3825 value: "Hello world!".to_string(),
3826 }))
3827 .unwrap();
3828
3829 data.apply(&patch);
3830 assert_eq!(
3831 external_crate::TheirType::Struct {
3832 value: "Hello world!".to_string()
3833 },
3834 data.0
3835 );
3836
3837 #[derive(Reflect, Debug, PartialEq)]
3839 enum ContainerEnum {
3840 Foo,
3841 Bar {
3842 #[reflect(remote = MyType)]
3843 their_type: external_crate::TheirType,
3844 },
3845 }
3846
3847 let patch = DynamicEnum::try_from(ContainerEnum::Bar {
3848 their_type: external_crate::TheirType::Tuple(123),
3849 })
3850 .unwrap();
3851
3852 let mut data = ContainerEnum::Foo;
3853
3854 assert_eq!(ContainerEnum::Foo, data);
3855 data.apply(&patch);
3856 assert_eq!(
3857 ContainerEnum::Bar {
3858 their_type: external_crate::TheirType::Tuple(123)
3859 },
3860 data
3861 );
3862 }
3863
3864 #[test]
3865 fn should_reflect_nested_remote_type() {
3866 mod external_crate {
3867 pub struct TheirOuter<T> {
3868 pub a: TheirInner<T>,
3869 pub b: TheirInner<bool>,
3870 }
3871
3872 pub struct TheirInner<T>(pub T);
3873 }
3874
3875 #[reflect_remote(external_crate::TheirOuter<T>)]
3876 struct MyOuter<T: FromReflect + Reflectable> {
3877 #[reflect(remote = MyInner<T>)]
3878 pub a: external_crate::TheirInner<T>,
3879 #[reflect(remote = MyInner<bool>)]
3880 pub b: external_crate::TheirInner<bool>,
3881 }
3882
3883 #[reflect_remote(external_crate::TheirInner<T>)]
3884 struct MyInner<T: FromReflect>(pub T);
3885
3886 let mut patch = DynamicStruct::default();
3887 patch.set_represented_type(Some(MyOuter::<i32>::type_info()));
3888 patch.insert("a", MyInner(external_crate::TheirInner(321_i32)));
3889 patch.insert("b", MyInner(external_crate::TheirInner(true)));
3890
3891 let mut data = MyOuter(external_crate::TheirOuter {
3892 a: external_crate::TheirInner(123_i32),
3893 b: external_crate::TheirInner(false),
3894 });
3895
3896 assert_eq!(123, data.0.a.0);
3897 assert!(!data.0.b.0);
3898 data.apply(&patch);
3899 assert_eq!(321, data.0.a.0);
3900 assert!(data.0.b.0);
3901 }
3902
3903 #[test]
3904 fn should_reflect_nested_remote_enum() {
3905 mod external_crate {
3906 use core::fmt::Debug;
3907
3908 #[derive(Debug)]
3909 pub enum TheirOuter<T: Debug> {
3910 Unit,
3911 Tuple(TheirInner<T>),
3912 Struct { value: TheirInner<T> },
3913 }
3914 #[derive(Debug)]
3915 pub enum TheirInner<T: Debug> {
3916 Unit,
3917 Tuple(T),
3918 Struct { value: T },
3919 }
3920 }
3921
3922 #[reflect_remote(external_crate::TheirOuter<T>)]
3923 #[derive(Debug)]
3924 enum MyOuter<T: FromReflect + Reflectable + Debug> {
3925 Unit,
3926 Tuple(#[reflect(remote = MyInner<T>)] external_crate::TheirInner<T>),
3927 Struct {
3928 #[reflect(remote = MyInner<T>)]
3929 value: external_crate::TheirInner<T>,
3930 },
3931 }
3932
3933 #[reflect_remote(external_crate::TheirInner<T>)]
3934 #[derive(Debug)]
3935 enum MyInner<T: FromReflect + Debug> {
3936 Unit,
3937 Tuple(T),
3938 Struct { value: T },
3939 }
3940
3941 let mut patch = DynamicEnum::default();
3942 let mut value = DynamicStruct::default();
3943 value.insert("value", MyInner(external_crate::TheirInner::Tuple(123)));
3944 patch.set_variant("Struct", value);
3945
3946 let mut data = MyOuter(external_crate::TheirOuter::<i32>::Unit);
3947
3948 assert!(matches!(
3949 data,
3950 MyOuter(external_crate::TheirOuter::<i32>::Unit)
3951 ));
3952 data.apply(&patch);
3953 assert!(matches!(
3954 data,
3955 MyOuter(external_crate::TheirOuter::Struct {
3956 value: external_crate::TheirInner::Tuple(123)
3957 })
3958 ));
3959 }
3960
3961 #[test]
3962 fn should_take_remote_type() {
3963 mod external_crate {
3964 use alloc::string::String;
3965
3966 #[derive(Debug, Default, PartialEq, Eq)]
3967 pub struct TheirType {
3968 pub value: String,
3969 }
3970 }
3971
3972 #[reflect_remote(external_crate::TheirType)]
3974 #[derive(Debug, Default)]
3975 #[reflect(Debug, Default)]
3976 struct MyType {
3977 pub value: String,
3978 }
3979
3980 let input: Box<dyn Reflect> = Box::new(MyType(external_crate::TheirType {
3981 value: "Hello".to_string(),
3982 }));
3983
3984 let output: external_crate::TheirType = input
3985 .take()
3986 .expect("should downcast to `external_crate::TheirType`");
3987 assert_eq!(
3988 external_crate::TheirType {
3989 value: "Hello".to_string(),
3990 },
3991 output
3992 );
3993 }
3994
3995 #[test]
3996 fn should_try_take_remote_type() {
3997 mod external_crate {
3998 use alloc::string::String;
3999
4000 #[derive(Debug, Default, PartialEq, Eq)]
4001 pub struct TheirType {
4002 pub value: String,
4003 }
4004 }
4005
4006 #[reflect_remote(external_crate::TheirType)]
4008 #[derive(Debug, Default)]
4009 #[reflect(Debug, Default)]
4010 struct MyType {
4011 pub value: String,
4012 }
4013
4014 let input: Box<dyn PartialReflect> = Box::new(MyType(external_crate::TheirType {
4015 value: "Hello".to_string(),
4016 }));
4017
4018 let output: external_crate::TheirType = input
4019 .try_take()
4020 .expect("should downcast to `external_crate::TheirType`");
4021 assert_eq!(
4022 external_crate::TheirType {
4023 value: "Hello".to_string(),
4024 },
4025 output,
4026 );
4027 }
4028
4029 #[test]
4030 fn should_take_nested_remote_type() {
4031 mod external_crate {
4032 #[derive(PartialEq, Eq, Debug)]
4033 pub struct TheirOuter<T> {
4034 pub inner: TheirInner<T>,
4035 }
4036 #[derive(PartialEq, Eq, Debug)]
4037 pub struct TheirInner<T>(pub T);
4038 }
4039
4040 #[reflect_remote(external_crate::TheirOuter<T>)]
4041 struct MyOuter<T: FromReflect + Reflectable> {
4042 #[reflect(remote = MyInner<T>)]
4043 pub inner: external_crate::TheirInner<T>,
4044 }
4045
4046 #[reflect_remote(external_crate::TheirInner<T>)]
4047 struct MyInner<T: FromReflect>(pub T);
4048
4049 let input: Box<dyn Reflect> = Box::new(MyOuter(external_crate::TheirOuter {
4050 inner: external_crate::TheirInner(123),
4051 }));
4052
4053 let output: external_crate::TheirOuter<i32> = input
4054 .take()
4055 .expect("should downcast to `external_crate::TheirOuter`");
4056 assert_eq!(
4057 external_crate::TheirOuter {
4058 inner: external_crate::TheirInner(123),
4059 },
4060 output
4061 );
4062 }
4063
4064 #[test]
4066 fn should_serialize_opaque_remote_type() {
4067 mod external_crate {
4068 use serde::{Deserialize, Serialize};
4069 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
4070 pub struct Vector2<T>(pub [T; 2]);
4071 }
4072
4073 #[reflect_remote(external_crate::Vector2<i32>)]
4074 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
4075 #[reflect(Serialize, Deserialize)]
4076 #[reflect(opaque)]
4077 struct Vector2Wrapper([i32; 2]);
4078
4079 #[derive(Reflect, Debug, PartialEq)]
4080 struct Point(#[reflect(remote = Vector2Wrapper)] external_crate::Vector2<i32>);
4081
4082 let point = Point(external_crate::Vector2([1, 2]));
4083
4084 let mut registry = TypeRegistry::new();
4085 registry.register::<Point>();
4086 registry.register::<Vector2Wrapper>();
4087
4088 let serializer = ReflectSerializer::new(&point, ®istry);
4089 let serialized = ron::to_string(&serializer).unwrap();
4090 assert_eq!(serialized, r#"{"bevy_reflect::tests::Point":((((1,2))))}"#);
4091
4092 let mut deserializer = Deserializer::from_str(&serialized).unwrap();
4093 let reflect_deserializer = ReflectDeserializer::new(®istry);
4094 let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
4095 let point = <Point as FromReflect>::from_reflect(&*deserialized).unwrap();
4096 assert_eq!(point, Point(external_crate::Vector2([1, 2])));
4097 }
4098
4099 #[test]
4100 fn should_register_fully_qualified_type_data() {
4101 mod foo {
4102 pub mod bar {
4103 use crate::CreateTypeData;
4104
4105 #[derive(Clone)]
4106 pub struct ReflectBaz;
4107
4108 impl<T> CreateTypeData<T> for ReflectBaz {
4109 fn create_type_data(_: ()) -> Self {
4110 Self
4111 }
4112 }
4113 }
4114 }
4115
4116 #[derive(Reflect)]
4117 #[reflect(foo::bar::Baz)]
4118 struct AutoPrefix;
4119
4120 #[derive(Reflect)]
4121 #[reflect(foo::bar::ReflectBaz)]
4122 struct ManualPrefix;
4123
4124 let mut registry = TypeRegistry::empty();
4125 registry.register::<AutoPrefix>();
4126 registry.register::<ManualPrefix>();
4127
4128 assert!(registry
4129 .get_type_data::<foo::bar::ReflectBaz>(TypeId::of::<AutoPrefix>())
4130 .is_some());
4131 assert!(registry
4132 .get_type_data::<foo::bar::ReflectBaz>(TypeId::of::<ManualPrefix>())
4133 .is_some());
4134 }
4135
4136 #[cfg(feature = "auto_register")]
4137 mod auto_register_reflect {
4138 use super::*;
4139
4140 #[test]
4141 fn should_ignore_auto_reflect_registration() {
4142 #[derive(Reflect)]
4143 #[reflect(no_auto_register)]
4144 struct NoAutomaticStruct {
4145 a: usize,
4146 }
4147
4148 let mut registry = TypeRegistry::default();
4149 registry.register_derived_types();
4150
4151 assert!(!registry.contains(TypeId::of::<NoAutomaticStruct>()));
4152 }
4153
4154 #[test]
4155 fn should_auto_register_reflect_for_all_supported_types() {
4156 #[derive(Reflect)]
4158 struct StructReflect {
4159 a: usize,
4160 }
4161
4162 #[derive(Reflect)]
4164 struct ZSTStructReflect;
4165
4166 #[derive(Reflect)]
4168 struct TupleStructReflect(pub u32);
4169
4170 #[derive(Reflect)]
4172 enum EnumReflect {
4173 A,
4174 B,
4175 }
4176
4177 #[derive(Reflect)]
4179 enum ZSTEnumReflect {}
4180
4181 #[derive(Reflect, Clone)]
4183 #[reflect(opaque)]
4184 struct OpaqueStructReflect {
4185 _a: usize,
4186 }
4187
4188 #[derive(Reflect, Clone)]
4190 #[reflect(opaque)]
4191 struct ZSTOpaqueStructReflect;
4192
4193 let mut registry = TypeRegistry::default();
4194 registry.register_derived_types();
4195
4196 assert!(registry.contains(TypeId::of::<StructReflect>()));
4197 assert!(registry.contains(TypeId::of::<ZSTStructReflect>()));
4198 assert!(registry.contains(TypeId::of::<TupleStructReflect>()));
4199 assert!(registry.contains(TypeId::of::<EnumReflect>()));
4200 assert!(registry.contains(TypeId::of::<ZSTEnumReflect>()));
4201 assert!(registry.contains(TypeId::of::<OpaqueStructReflect>()));
4202 assert!(registry.contains(TypeId::of::<ZSTOpaqueStructReflect>()));
4203 }
4204
4205 #[test]
4206 fn type_data_dependency() {
4207 #[derive(Reflect)]
4208 #[reflect(A)]
4209 struct X;
4210
4211 #[derive(Clone)]
4212 struct ReflectA;
4213
4214 impl<T> CreateTypeData<T> for ReflectA {
4215 fn create_type_data(_input: ()) -> Self {
4216 ReflectA
4217 }
4218
4219 fn insert_dependencies(type_registration: &mut TypeRegistration) {
4220 type_registration.insert(ReflectB);
4221 }
4222 }
4223
4224 #[derive(Clone)]
4225 struct ReflectB;
4226
4227 let mut registry = TypeRegistry::new();
4228 registry.register::<X>();
4229
4230 let registration = registry.get(TypeId::of::<X>()).unwrap();
4231 assert!(registration.data::<ReflectA>().is_some());
4232 assert!(registration.data::<ReflectB>().is_some());
4233 }
4234 }
4235
4236 #[cfg(feature = "glam")]
4237 mod glam {
4238 use super::*;
4239 use ::glam::{quat, vec3, Quat, Vec3};
4240
4241 #[test]
4242 fn quat_serialization() {
4243 let q = quat(1.0, 2.0, 3.0, 4.0);
4244
4245 let mut registry = TypeRegistry::default();
4246 registry.register::<f32>();
4247 registry.register::<Quat>();
4248
4249 let ser = ReflectSerializer::new(&q, ®istry);
4250
4251 let config = PrettyConfig::default()
4252 .new_line(String::from("\n"))
4253 .indentor(String::from(" "));
4254 let output = to_string_pretty(&ser, config).unwrap();
4255 let expected = r#"
4256{
4257 "glam::Quat": (1.0, 2.0, 3.0, 4.0),
4258}"#;
4259
4260 assert_eq!(expected, format!("\n{output}"));
4261 }
4262
4263 #[test]
4264 fn quat_deserialization() {
4265 let data = r#"
4266{
4267 "glam::Quat": (1.0, 2.0, 3.0, 4.0),
4268}"#;
4269
4270 let mut registry = TypeRegistry::default();
4271 registry.register::<Quat>();
4272 registry.register::<f32>();
4273
4274 let de = ReflectDeserializer::new(®istry);
4275
4276 let mut deserializer =
4277 Deserializer::from_str(data).expect("Failed to acquire deserializer");
4278
4279 let dynamic_struct = de
4280 .deserialize(&mut deserializer)
4281 .expect("Failed to deserialize");
4282
4283 let mut result = Quat::default();
4284
4285 result.apply(dynamic_struct.as_partial_reflect());
4286
4287 assert_eq!(result, quat(1.0, 2.0, 3.0, 4.0));
4288 }
4289
4290 #[test]
4291 fn vec3_serialization() {
4292 let v = vec3(12.0, 3.0, -6.9);
4293
4294 let mut registry = TypeRegistry::default();
4295 registry.register::<f32>();
4296 registry.register::<Vec3>();
4297
4298 let ser = ReflectSerializer::new(&v, ®istry);
4299
4300 let config = PrettyConfig::default()
4301 .new_line(String::from("\n"))
4302 .indentor(String::from(" "));
4303 let output = to_string_pretty(&ser, config).unwrap();
4304 let expected = r#"
4305{
4306 "glam::Vec3": (12.0, 3.0, -6.9),
4307}"#;
4308
4309 assert_eq!(expected, format!("\n{output}"));
4310 }
4311
4312 #[test]
4313 fn vec3_deserialization() {
4314 let data = r#"
4315{
4316 "glam::Vec3": (12.0, 3.0, -6.9),
4317}"#;
4318
4319 let mut registry = TypeRegistry::default();
4320 registry.add_registration(Vec3::get_type_registration());
4321 registry.add_registration(f32::get_type_registration());
4322
4323 let de = ReflectDeserializer::new(®istry);
4324
4325 let mut deserializer =
4326 Deserializer::from_str(data).expect("Failed to acquire deserializer");
4327
4328 let dynamic_struct = de
4329 .deserialize(&mut deserializer)
4330 .expect("Failed to deserialize");
4331
4332 let mut result = Vec3::default();
4333
4334 result.apply(dynamic_struct.as_partial_reflect());
4335
4336 assert_eq!(result, vec3(12.0, 3.0, -6.9));
4337 }
4338
4339 #[test]
4340 fn vec3_field_access() {
4341 let mut v = vec3(1.0, 2.0, 3.0);
4342
4343 assert_eq!(*v.get_field::<f32>("x").unwrap(), 1.0);
4344
4345 *v.get_field_mut::<f32>("y").unwrap() = 6.0;
4346
4347 assert_eq!(v.y, 6.0);
4348 }
4349
4350 #[test]
4351 fn vec3_path_access() {
4352 let mut v = vec3(1.0, 2.0, 3.0);
4353
4354 assert_eq!(
4355 *v.reflect_path("x")
4356 .unwrap()
4357 .try_downcast_ref::<f32>()
4358 .unwrap(),
4359 1.0
4360 );
4361
4362 *v.reflect_path_mut("y")
4363 .unwrap()
4364 .try_downcast_mut::<f32>()
4365 .unwrap() = 6.0;
4366
4367 assert_eq!(v.y, 6.0);
4368 }
4369
4370 #[test]
4371 fn vec3_apply_dynamic() {
4372 let mut v = vec3(3.0, 3.0, 3.0);
4373
4374 let mut d = DynamicStruct::default();
4375 d.insert("x", 4.0f32);
4376 d.insert("y", 2.0f32);
4377 d.insert("z", 1.0f32);
4378
4379 v.apply(&d);
4380
4381 assert_eq!(v, vec3(4.0, 2.0, 1.0));
4382 }
4383 }
4384}