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