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