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