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