1#![allow(missing_docs)]
3#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4#![doc(
5 html_logo_url = "https://bevyengine.org/assets/icon.png",
6 html_favicon_url = "https://bevyengine.org/assets/icon.png"
7)]
8
9mod array;
477mod fields;
478mod from_reflect;
479mod list;
480mod map;
481mod path;
482mod reflect;
483mod struct_trait;
484mod tuple;
485mod tuple_struct;
486mod type_info;
487mod type_path;
488mod type_registry;
489
490mod impls {
491 #[cfg(feature = "glam")]
492 mod glam;
493 #[cfg(feature = "petgraph")]
494 mod petgraph;
495 #[cfg(feature = "smallvec")]
496 mod smallvec;
497 #[cfg(feature = "smol_str")]
498 mod smol_str;
499
500 mod std;
501 #[cfg(feature = "uuid")]
502 mod uuid;
503}
504
505pub mod attributes;
506mod enums;
507pub mod serde;
508pub mod std_traits;
509pub mod utility;
510
511pub mod prelude {
512 pub use crate::std_traits::*;
513 #[doc(hidden)]
514 pub use crate::{
515 reflect_trait, FromReflect, GetField, GetPath, GetTupleStructField, Reflect,
516 ReflectDeserialize, ReflectFromReflect, ReflectPath, ReflectSerialize, Struct, TupleStruct,
517 TypePath,
518 };
519}
520
521pub use array::*;
522pub use enums::*;
523pub use fields::*;
524pub use from_reflect::*;
525pub use list::*;
526pub use map::*;
527pub use path::*;
528pub use reflect::*;
529pub use struct_trait::*;
530pub use tuple::*;
531pub use tuple_struct::*;
532pub use type_info::*;
533pub use type_path::*;
534pub use type_registry::*;
535
536pub use bevy_reflect_derive::*;
537pub use erased_serde;
538
539extern crate alloc;
540
541#[doc(hidden)]
545pub mod __macro_exports {
546 use crate::{
547 DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, DynamicTuple,
548 DynamicTupleStruct, GetTypeRegistration, TypeRegistry,
549 };
550
551 pub trait RegisterForReflection {
560 #[allow(unused_variables)]
561 fn __register(registry: &mut TypeRegistry) {}
562 }
563
564 impl<T: GetTypeRegistration> RegisterForReflection for T {
565 fn __register(registry: &mut TypeRegistry) {
566 registry.register::<T>();
567 }
568 }
569
570 impl RegisterForReflection for DynamicEnum {}
571
572 impl RegisterForReflection for DynamicTupleStruct {}
573
574 impl RegisterForReflection for DynamicStruct {}
575
576 impl RegisterForReflection for DynamicMap {}
577
578 impl RegisterForReflection for DynamicList {}
579
580 impl RegisterForReflection for DynamicArray {}
581
582 impl RegisterForReflection for DynamicTuple {}
583}
584
585#[cfg(test)]
586#[allow(clippy::disallowed_types, clippy::approx_constant)]
587mod tests {
588 use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
589 use bevy_utils::HashMap;
590 use ron::{
591 ser::{to_string_pretty, PrettyConfig},
592 Deserializer,
593 };
594 use static_assertions::{assert_impl_all, assert_not_impl_all};
595 use std::{
596 any::TypeId,
597 borrow::Cow,
598 fmt::{Debug, Formatter},
599 marker::PhantomData,
600 };
601
602 use super::prelude::*;
603 use super::*;
604 use crate as bevy_reflect;
605 use crate::serde::{ReflectDeserializer, ReflectSerializer};
606 use crate::utility::GenericTypePathCell;
607
608 #[test]
609 fn try_apply_should_detect_kinds() {
610 #[derive(Reflect, Debug)]
611 struct Struct {
612 a: u32,
613 b: f32,
614 }
615
616 #[derive(Reflect, Debug)]
617 enum Enum {
618 A,
619 B(u32),
620 }
621
622 let mut struct_target = Struct {
623 a: 0xDEADBEEF,
624 b: 3.14,
625 };
626
627 let mut enum_target = Enum::A;
628
629 let array_src = [8, 0, 8];
630
631 let result = struct_target.try_apply(&enum_target);
632 assert!(
633 matches!(
634 result,
635 Err(ApplyError::MismatchedKinds {
636 from_kind: ReflectKind::Enum,
637 to_kind: ReflectKind::Struct
638 })
639 ),
640 "result was {result:?}"
641 );
642
643 let result = enum_target.try_apply(&array_src);
644 assert!(
645 matches!(
646 result,
647 Err(ApplyError::MismatchedKinds {
648 from_kind: ReflectKind::Array,
649 to_kind: ReflectKind::Enum
650 })
651 ),
652 "result was {result:?}"
653 );
654 }
655
656 #[test]
657 fn reflect_struct() {
658 #[derive(Reflect)]
659 struct Foo {
660 a: u32,
661 b: f32,
662 c: Bar,
663 }
664 #[derive(Reflect)]
665 struct Bar {
666 x: u32,
667 }
668
669 let mut foo = Foo {
670 a: 42,
671 b: 3.14,
672 c: Bar { x: 1 },
673 };
674
675 let a = *foo.get_field::<u32>("a").unwrap();
676 assert_eq!(a, 42);
677
678 *foo.get_field_mut::<u32>("a").unwrap() += 1;
679 assert_eq!(foo.a, 43);
680
681 let bar = foo.get_field::<Bar>("c").unwrap();
682 assert_eq!(bar.x, 1);
683
684 let c = foo.field("c").unwrap();
686 if let ReflectRef::Struct(value) = c.reflect_ref() {
687 assert_eq!(*value.get_field::<u32>("x").unwrap(), 1);
688 } else {
689 panic!("Expected a struct.");
690 }
691
692 let mut dynamic_struct = DynamicStruct::default();
694 dynamic_struct.insert("a", 123u32);
695 dynamic_struct.insert("should_be_ignored", 456);
696
697 foo.apply(&dynamic_struct);
698 assert_eq!(foo.a, 123);
699 }
700
701 #[test]
702 fn reflect_map() {
703 #[derive(Reflect, Hash)]
704 #[reflect(Hash)]
705 struct Foo {
706 a: u32,
707 b: String,
708 }
709
710 let key_a = Foo {
711 a: 1,
712 b: "k1".to_string(),
713 };
714
715 let key_b = Foo {
716 a: 1,
717 b: "k1".to_string(),
718 };
719
720 let key_c = Foo {
721 a: 3,
722 b: "k3".to_string(),
723 };
724
725 let mut map = DynamicMap::default();
726 map.insert(key_a, 10u32);
727 assert_eq!(10, *map.get(&key_b).unwrap().downcast_ref::<u32>().unwrap());
728 assert!(map.get(&key_c).is_none());
729 *map.get_mut(&key_b).unwrap().downcast_mut::<u32>().unwrap() = 20;
730 assert_eq!(20, *map.get(&key_b).unwrap().downcast_ref::<u32>().unwrap());
731 }
732
733 #[test]
734 #[allow(clippy::disallowed_types)]
735 fn reflect_unit_struct() {
736 #[derive(Reflect)]
737 struct Foo(u32, u64);
738
739 let mut foo = Foo(1, 2);
740 assert_eq!(1, *foo.get_field::<u32>(0).unwrap());
741 assert_eq!(2, *foo.get_field::<u64>(1).unwrap());
742
743 let mut patch = DynamicTupleStruct::default();
744 patch.insert(3u32);
745 patch.insert(4u64);
746 assert_eq!(3, *patch.field(0).unwrap().downcast_ref::<u32>().unwrap());
747 assert_eq!(4, *patch.field(1).unwrap().downcast_ref::<u64>().unwrap());
748
749 foo.apply(&patch);
750 assert_eq!(3, foo.0);
751 assert_eq!(4, foo.1);
752
753 let mut iter = patch.iter_fields();
754 assert_eq!(3, *iter.next().unwrap().downcast_ref::<u32>().unwrap());
755 assert_eq!(4, *iter.next().unwrap().downcast_ref::<u64>().unwrap());
756 }
757
758 #[test]
759 #[should_panic(expected = "the given key bevy_reflect::tests::Foo does not support hashing")]
760 fn reflect_map_no_hash() {
761 #[derive(Reflect)]
762 struct Foo {
763 a: u32,
764 }
765
766 let foo = Foo { a: 1 };
767
768 let mut map = DynamicMap::default();
769 map.insert(foo, 10u32);
770 }
771
772 #[test]
773 fn reflect_ignore() {
774 #[derive(Reflect)]
775 struct Foo {
776 a: u32,
777 #[reflect(ignore)]
778 _b: u32,
779 }
780
781 let foo = Foo { a: 1, _b: 2 };
782
783 let values: Vec<u32> = foo
784 .iter_fields()
785 .map(|value| *value.downcast_ref::<u32>().unwrap())
786 .collect();
787 assert_eq!(values, vec![1]);
788 }
789
790 #[test]
791 fn should_call_from_reflect_dynamically() {
792 #[derive(Reflect)]
793 struct MyStruct {
794 foo: usize,
795 }
796
797 let mut registry = TypeRegistry::default();
799 registry.register::<MyStruct>();
800
801 let type_id = TypeId::of::<MyStruct>();
803 let rfr = registry
804 .get_type_data::<ReflectFromReflect>(type_id)
805 .expect("the FromReflect trait should be registered");
806
807 let mut dynamic_struct = DynamicStruct::default();
809 dynamic_struct.insert("foo", 123usize);
810 let reflected = rfr
811 .from_reflect(&dynamic_struct)
812 .expect("the type should be properly reflected");
813
814 let expected = MyStruct { foo: 123 };
816 assert!(expected
817 .reflect_partial_eq(reflected.as_ref())
818 .unwrap_or_default());
819 let not_expected = MyStruct { foo: 321 };
820 assert!(!not_expected
821 .reflect_partial_eq(reflected.as_ref())
822 .unwrap_or_default());
823 }
824
825 #[test]
826 fn from_reflect_should_allow_ignored_unnamed_fields() {
827 #[derive(Reflect, Eq, PartialEq, Debug)]
828 struct MyTupleStruct(i8, #[reflect(ignore)] i16, i32);
829
830 let expected = MyTupleStruct(1, 0, 3);
831
832 let mut dyn_tuple_struct = DynamicTupleStruct::default();
833 dyn_tuple_struct.insert(1_i8);
834 dyn_tuple_struct.insert(3_i32);
835 let my_tuple_struct = <MyTupleStruct as FromReflect>::from_reflect(&dyn_tuple_struct);
836
837 assert_eq!(Some(expected), my_tuple_struct);
838
839 #[derive(Reflect, Eq, PartialEq, Debug)]
840 enum MyEnum {
841 Tuple(i8, #[reflect(ignore)] i16, i32),
842 }
843
844 let expected = MyEnum::Tuple(1, 0, 3);
845
846 let mut dyn_tuple = DynamicTuple::default();
847 dyn_tuple.insert(1_i8);
848 dyn_tuple.insert(3_i32);
849
850 let mut dyn_enum = DynamicEnum::default();
851 dyn_enum.set_variant("Tuple", dyn_tuple);
852
853 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
854
855 assert_eq!(Some(expected), my_enum);
856 }
857
858 #[test]
859 fn from_reflect_should_use_default_field_attributes() {
860 #[derive(Reflect, Eq, PartialEq, Debug)]
861 struct MyStruct {
862 #[reflect(default)]
865 foo: String,
866
867 #[reflect(ignore)]
869 #[reflect(default = "get_bar_default")]
870 bar: NotReflect,
871
872 #[reflect(ignore, default = "get_bar_default")]
874 baz: NotReflect,
875 }
876
877 #[derive(Eq, PartialEq, Debug)]
878 struct NotReflect(usize);
879
880 fn get_bar_default() -> NotReflect {
881 NotReflect(123)
882 }
883
884 let expected = MyStruct {
885 foo: String::default(),
886 bar: NotReflect(123),
887 baz: NotReflect(123),
888 };
889
890 let dyn_struct = DynamicStruct::default();
891 let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
892
893 assert_eq!(Some(expected), my_struct);
894 }
895
896 #[test]
897 fn from_reflect_should_use_default_variant_field_attributes() {
898 #[derive(Reflect, Eq, PartialEq, Debug)]
899 enum MyEnum {
900 Foo(#[reflect(default)] String),
901 Bar {
902 #[reflect(default = "get_baz_default")]
903 #[reflect(ignore)]
904 baz: usize,
905 },
906 }
907
908 fn get_baz_default() -> usize {
909 123
910 }
911
912 let expected = MyEnum::Foo(String::default());
913
914 let dyn_enum = DynamicEnum::new("Foo", DynamicTuple::default());
915 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
916
917 assert_eq!(Some(expected), my_enum);
918
919 let expected = MyEnum::Bar {
920 baz: get_baz_default(),
921 };
922
923 let dyn_enum = DynamicEnum::new("Bar", DynamicStruct::default());
924 let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
925
926 assert_eq!(Some(expected), my_enum);
927 }
928
929 #[test]
930 fn from_reflect_should_use_default_container_attribute() {
931 #[derive(Reflect, Eq, PartialEq, Debug)]
932 #[reflect(Default)]
933 struct MyStruct {
934 foo: String,
935 #[reflect(ignore)]
936 bar: usize,
937 }
938
939 impl Default for MyStruct {
940 fn default() -> Self {
941 Self {
942 foo: String::from("Hello"),
943 bar: 123,
944 }
945 }
946 }
947
948 let expected = MyStruct {
949 foo: String::from("Hello"),
950 bar: 123,
951 };
952
953 let dyn_struct = DynamicStruct::default();
954 let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
955
956 assert_eq!(Some(expected), my_struct);
957 }
958
959 #[test]
960 fn reflect_complex_patch() {
961 #[derive(Reflect, Eq, PartialEq, Debug)]
962 #[reflect(PartialEq)]
963 struct Foo {
964 a: u32,
965 #[reflect(ignore)]
966 _b: u32,
967 c: Vec<isize>,
968 d: HashMap<usize, i8>,
969 e: Bar,
970 f: (i32, Vec<isize>, Bar),
971 g: Vec<(Baz, HashMap<usize, Bar>)>,
972 h: [u32; 2],
973 }
974
975 #[derive(Reflect, Eq, PartialEq, Clone, Debug)]
976 #[reflect(PartialEq)]
977 struct Bar {
978 x: u32,
979 }
980
981 #[derive(Reflect, Eq, PartialEq, Debug)]
982 struct Baz(String);
983
984 let mut hash_map = HashMap::default();
985 hash_map.insert(1, 1);
986 hash_map.insert(2, 2);
987
988 let mut hash_map_baz = HashMap::default();
989 hash_map_baz.insert(1, Bar { x: 0 });
990
991 let mut foo = Foo {
992 a: 1,
993 _b: 1,
994 c: vec![1, 2],
995 d: hash_map,
996 e: Bar { x: 1 },
997 f: (1, vec![1, 2], Bar { x: 1 }),
998 g: vec![(Baz("string".to_string()), hash_map_baz)],
999 h: [2; 2],
1000 };
1001
1002 let mut foo_patch = DynamicStruct::default();
1003 foo_patch.insert("a", 2u32);
1004 foo_patch.insert("b", 2u32); let mut list = DynamicList::default();
1007 list.push(3isize);
1008 list.push(4isize);
1009 list.push(5isize);
1010 foo_patch.insert("c", list.clone_dynamic());
1011
1012 let mut map = DynamicMap::default();
1013 map.insert(2usize, 3i8);
1014 map.insert(3usize, 4i8);
1015 foo_patch.insert("d", map);
1016
1017 let mut bar_patch = DynamicStruct::default();
1018 bar_patch.insert("x", 2u32);
1019 foo_patch.insert("e", bar_patch.clone_dynamic());
1020
1021 let mut tuple = DynamicTuple::default();
1022 tuple.insert(2i32);
1023 tuple.insert(list);
1024 tuple.insert(bar_patch);
1025 foo_patch.insert("f", tuple);
1026
1027 let mut composite = DynamicList::default();
1028 composite.push({
1029 let mut tuple = DynamicTuple::default();
1030 tuple.insert({
1031 let mut tuple_struct = DynamicTupleStruct::default();
1032 tuple_struct.insert("new_string".to_string());
1033 tuple_struct
1034 });
1035 tuple.insert({
1036 let mut map = DynamicMap::default();
1037 map.insert(1usize, {
1038 let mut struct_ = DynamicStruct::default();
1039 struct_.insert("x", 7u32);
1040 struct_
1041 });
1042 map
1043 });
1044 tuple
1045 });
1046 foo_patch.insert("g", composite);
1047
1048 let array = DynamicArray::from_vec(vec![2u32, 2u32]);
1049 foo_patch.insert("h", array);
1050
1051 foo.apply(&foo_patch);
1052
1053 let mut hash_map = HashMap::default();
1054 hash_map.insert(1, 1);
1055 hash_map.insert(2, 3);
1056 hash_map.insert(3, 4);
1057
1058 let mut hash_map_baz = HashMap::default();
1059 hash_map_baz.insert(1, Bar { x: 7 });
1060
1061 let expected_foo = Foo {
1062 a: 2,
1063 _b: 1,
1064 c: vec![3, 4, 5],
1065 d: hash_map,
1066 e: Bar { x: 2 },
1067 f: (2, vec![3, 4, 5], Bar { x: 2 }),
1068 g: vec![(Baz("new_string".to_string()), hash_map_baz.clone())],
1069 h: [2; 2],
1070 };
1071
1072 assert_eq!(foo, expected_foo);
1073
1074 let new_foo = Foo::from_reflect(&foo_patch)
1075 .expect("error while creating a concrete type from a dynamic type");
1076
1077 let mut hash_map = HashMap::default();
1078 hash_map.insert(2, 3);
1079 hash_map.insert(3, 4);
1080
1081 let expected_new_foo = Foo {
1082 a: 2,
1083 _b: 0,
1084 c: vec![3, 4, 5],
1085 d: hash_map,
1086 e: Bar { x: 2 },
1087 f: (2, vec![3, 4, 5], Bar { x: 2 }),
1088 g: vec![(Baz("new_string".to_string()), hash_map_baz)],
1089 h: [2; 2],
1090 };
1091
1092 assert_eq!(new_foo, expected_new_foo);
1093 }
1094
1095 #[test]
1096 fn should_auto_register_fields() {
1097 #[derive(Reflect)]
1098 struct Foo {
1099 bar: Bar,
1100 }
1101
1102 #[derive(Reflect)]
1103 enum Bar {
1104 Variant(Baz),
1105 }
1106
1107 #[derive(Reflect)]
1108 struct Baz(usize);
1109
1110 let mut registry = TypeRegistry::empty();
1112 registry.register::<Foo>();
1113
1114 assert!(
1115 registry.contains(TypeId::of::<Bar>()),
1116 "registry should contain auto-registered `Bar` from `Foo`"
1117 );
1118
1119 let mut registry = TypeRegistry::empty();
1121 registry.register::<Option<Foo>>();
1122
1123 assert!(
1124 registry.contains(TypeId::of::<Bar>()),
1125 "registry should contain auto-registered `Bar` from `Option<Foo>`"
1126 );
1127
1128 let mut registry = TypeRegistry::empty();
1130 registry.register::<(Foo, Foo)>();
1131
1132 assert!(
1133 registry.contains(TypeId::of::<Bar>()),
1134 "registry should contain auto-registered `Bar` from `(Foo, Foo)`"
1135 );
1136
1137 let mut registry = TypeRegistry::empty();
1139 registry.register::<[Foo; 3]>();
1140
1141 assert!(
1142 registry.contains(TypeId::of::<Bar>()),
1143 "registry should contain auto-registered `Bar` from `[Foo; 3]`"
1144 );
1145
1146 let mut registry = TypeRegistry::empty();
1148 registry.register::<Vec<Foo>>();
1149
1150 assert!(
1151 registry.contains(TypeId::of::<Bar>()),
1152 "registry should contain auto-registered `Bar` from `Vec<Foo>`"
1153 );
1154
1155 let mut registry = TypeRegistry::empty();
1157 registry.register::<HashMap<i32, Foo>>();
1158
1159 assert!(
1160 registry.contains(TypeId::of::<Bar>()),
1161 "registry should contain auto-registered `Bar` from `HashMap<i32, Foo>`"
1162 );
1163 }
1164
1165 #[test]
1166 fn should_allow_dynamic_fields() {
1167 #[derive(Reflect)]
1168 #[reflect(from_reflect = false)]
1169 struct MyStruct(
1170 DynamicEnum,
1171 DynamicTupleStruct,
1172 DynamicStruct,
1173 DynamicMap,
1174 DynamicList,
1175 DynamicArray,
1176 DynamicTuple,
1177 i32,
1178 );
1179
1180 assert_impl_all!(MyStruct: Reflect, GetTypeRegistration);
1181
1182 let mut registry = TypeRegistry::empty();
1183 registry.register::<MyStruct>();
1184
1185 assert_eq!(2, registry.iter().count());
1186 assert!(registry.contains(TypeId::of::<MyStruct>()));
1187 assert!(registry.contains(TypeId::of::<i32>()));
1188 }
1189
1190 #[test]
1191 fn should_not_auto_register_existing_types() {
1192 #[derive(Reflect)]
1193 struct Foo {
1194 bar: Bar,
1195 }
1196
1197 #[derive(Reflect, Default)]
1198 struct Bar(usize);
1199
1200 let mut registry = TypeRegistry::empty();
1201 registry.register::<Bar>();
1202 registry.register_type_data::<Bar, ReflectDefault>();
1203 registry.register::<Foo>();
1204
1205 assert!(
1206 registry
1207 .get_type_data::<ReflectDefault>(TypeId::of::<Bar>())
1208 .is_some(),
1209 "registry should contain existing registration for `Bar`"
1210 );
1211 }
1212
1213 #[test]
1214 fn reflect_serialize() {
1215 #[derive(Reflect)]
1216 struct Foo {
1217 a: u32,
1218 #[reflect(ignore)]
1219 _b: u32,
1220 c: Vec<isize>,
1221 d: HashMap<usize, i8>,
1222 e: Bar,
1223 f: String,
1224 g: (i32, Vec<isize>, Bar),
1225 h: [u32; 2],
1226 }
1227
1228 #[derive(Reflect, Serialize, Deserialize)]
1229 #[reflect(Serialize, Deserialize)]
1230 struct Bar {
1231 x: u32,
1232 }
1233
1234 let mut hash_map = HashMap::default();
1235 hash_map.insert(1, 1);
1236 hash_map.insert(2, 2);
1237 let foo = Foo {
1238 a: 1,
1239 _b: 1,
1240 c: vec![1, 2],
1241 d: hash_map,
1242 e: Bar { x: 1 },
1243 f: "hi".to_string(),
1244 g: (1, vec![1, 2], Bar { x: 1 }),
1245 h: [2; 2],
1246 };
1247
1248 let mut registry = TypeRegistry::default();
1249 registry.register::<u32>();
1250 registry.register::<i8>();
1251 registry.register::<i32>();
1252 registry.register::<usize>();
1253 registry.register::<isize>();
1254 registry.register::<Foo>();
1255 registry.register::<Bar>();
1256 registry.register::<String>();
1257 registry.register::<Vec<isize>>();
1258 registry.register::<HashMap<usize, i8>>();
1259 registry.register::<(i32, Vec<isize>, Bar)>();
1260 registry.register::<[u32; 2]>();
1261
1262 let serializer = ReflectSerializer::new(&foo, ®istry);
1263 let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
1264
1265 let mut deserializer = Deserializer::from_str(&serialized).unwrap();
1266 let reflect_deserializer = ReflectDeserializer::new(®istry);
1267 let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
1268 let dynamic_struct = value.take::<DynamicStruct>().unwrap();
1269
1270 assert!(foo.reflect_partial_eq(&dynamic_struct).unwrap());
1271 }
1272
1273 #[test]
1274 fn reflect_downcast() {
1275 #[derive(Reflect, Clone, Debug, PartialEq)]
1276 struct Bar {
1277 y: u8,
1278 }
1279
1280 #[derive(Reflect, Clone, Debug, PartialEq)]
1281 struct Foo {
1282 x: i32,
1283 s: String,
1284 b: Bar,
1285 u: usize,
1286 t: ([f32; 3], String),
1287 v: Cow<'static, str>,
1288 w: Cow<'static, [u8]>,
1289 }
1290
1291 let foo = Foo {
1292 x: 123,
1293 s: "String".to_string(),
1294 b: Bar { y: 255 },
1295 u: 1111111111111,
1296 t: ([3.0, 2.0, 1.0], "Tuple String".to_string()),
1297 v: Cow::Owned("Cow String".to_string()),
1298 w: Cow::Owned(vec![1, 2, 3]),
1299 };
1300
1301 let foo2: Box<dyn Reflect> = Box::new(foo.clone());
1302
1303 assert_eq!(foo, *foo2.downcast::<Foo>().unwrap());
1304 }
1305
1306 #[test]
1307 fn should_drain_fields() {
1308 let array_value: Box<dyn Array> = Box::new([123_i32, 321_i32]);
1309 let fields = array_value.drain();
1310 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1311 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1312
1313 let list_value: Box<dyn List> = Box::new(vec![123_i32, 321_i32]);
1314 let fields = list_value.drain();
1315 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1316 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1317
1318 let tuple_value: Box<dyn Tuple> = Box::new((123_i32, 321_i32));
1319 let fields = tuple_value.drain();
1320 assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1321 assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1322
1323 let map_value: Box<dyn Map> = Box::new(HashMap::from([(123_i32, 321_i32)]));
1324 let fields = map_value.drain();
1325 assert!(fields[0].0.reflect_partial_eq(&123_i32).unwrap_or_default());
1326 assert!(fields[0].1.reflect_partial_eq(&321_i32).unwrap_or_default());
1327 }
1328
1329 #[test]
1330 fn reflect_take() {
1331 #[derive(Reflect, Debug, PartialEq)]
1332 #[reflect(PartialEq)]
1333 struct Bar {
1334 x: u32,
1335 }
1336
1337 let x: Box<dyn Reflect> = Box::new(Bar { x: 2 });
1338 let y = x.take::<Bar>().unwrap();
1339 assert_eq!(y, Bar { x: 2 });
1340 }
1341
1342 #[test]
1343 fn not_dynamic_names() {
1344 let list = Vec::<usize>::new();
1345 let dyn_list = list.clone_dynamic();
1346 assert_ne!(dyn_list.reflect_type_path(), Vec::<usize>::type_path());
1347
1348 let array = [b'0'; 4];
1349 let dyn_array = array.clone_dynamic();
1350 assert_ne!(dyn_array.reflect_type_path(), <[u8; 4]>::type_path());
1351
1352 let map = HashMap::<usize, String>::default();
1353 let dyn_map = map.clone_dynamic();
1354 assert_ne!(
1355 dyn_map.reflect_type_path(),
1356 HashMap::<usize, String>::type_path()
1357 );
1358
1359 let tuple = (0usize, "1".to_string(), 2.0f32);
1360 let mut dyn_tuple = tuple.clone_dynamic();
1361 dyn_tuple.insert::<usize>(3);
1362 assert_ne!(
1363 dyn_tuple.reflect_type_path(),
1364 <(usize, String, f32, usize)>::type_path()
1365 );
1366
1367 #[derive(Reflect)]
1368 struct TestStruct {
1369 a: usize,
1370 }
1371 let struct_ = TestStruct { a: 0 };
1372 let dyn_struct = struct_.clone_dynamic();
1373 assert_ne!(dyn_struct.reflect_type_path(), TestStruct::type_path());
1374
1375 #[derive(Reflect)]
1376 struct TestTupleStruct(usize);
1377 let tuple_struct = TestTupleStruct(0);
1378 let dyn_tuple_struct = tuple_struct.clone_dynamic();
1379 assert_ne!(
1380 dyn_tuple_struct.reflect_type_path(),
1381 TestTupleStruct::type_path()
1382 );
1383 }
1384
1385 macro_rules! assert_type_paths {
1386 ($($ty:ty => $long:literal, $short:literal,)*) => {
1387 $(
1388 assert_eq!(<$ty as TypePath>::type_path(), $long);
1389 assert_eq!(<$ty as TypePath>::short_type_path(), $short);
1390 )*
1391 };
1392 }
1393
1394 #[test]
1395 fn reflect_type_path() {
1396 #[derive(TypePath)]
1397 struct Param;
1398
1399 #[derive(TypePath)]
1400 struct Derive;
1401
1402 #[derive(TypePath)]
1403 #[type_path = "my_alias"]
1404 struct DerivePath;
1405
1406 #[derive(TypePath)]
1407 #[type_path = "my_alias"]
1408 #[type_name = "MyDerivePathName"]
1409 struct DerivePathName;
1410
1411 #[derive(TypePath)]
1412 struct DeriveG<T>(PhantomData<T>);
1413
1414 #[derive(TypePath)]
1415 #[type_path = "my_alias"]
1416 struct DerivePathG<T, const N: usize>(PhantomData<T>);
1417
1418 #[derive(TypePath)]
1419 #[type_path = "my_alias"]
1420 #[type_name = "MyDerivePathNameG"]
1421 struct DerivePathNameG<T>(PhantomData<T>);
1422
1423 struct Macro;
1424 impl_type_path!((in my_alias) Macro);
1425
1426 struct MacroName;
1427 impl_type_path!((in my_alias as MyMacroName) MacroName);
1428
1429 struct MacroG<T, const N: usize>(PhantomData<T>);
1430 impl_type_path!((in my_alias) MacroG<T, const N: usize>);
1431
1432 struct MacroNameG<T>(PhantomData<T>);
1433 impl_type_path!((in my_alias as MyMacroNameG) MacroNameG<T>);
1434
1435 assert_type_paths! {
1436 Derive => "bevy_reflect::tests::Derive", "Derive",
1437 DerivePath => "my_alias::DerivePath", "DerivePath",
1438 DerivePathName => "my_alias::MyDerivePathName", "MyDerivePathName",
1439 DeriveG<Param> => "bevy_reflect::tests::DeriveG<bevy_reflect::tests::Param>", "DeriveG<Param>",
1440 DerivePathG<Param, 10> => "my_alias::DerivePathG<bevy_reflect::tests::Param, 10>", "DerivePathG<Param, 10>",
1441 DerivePathNameG<Param> => "my_alias::MyDerivePathNameG<bevy_reflect::tests::Param>", "MyDerivePathNameG<Param>",
1442 Macro => "my_alias::Macro", "Macro",
1443 MacroName => "my_alias::MyMacroName", "MyMacroName",
1444 MacroG<Param, 10> => "my_alias::MacroG<bevy_reflect::tests::Param, 10>", "MacroG<Param, 10>",
1445 MacroNameG<Param> => "my_alias::MyMacroNameG<bevy_reflect::tests::Param>", "MyMacroNameG<Param>",
1446 }
1447 }
1448
1449 #[test]
1450 fn std_type_paths() {
1451 #[derive(Clone)]
1452 struct Type;
1453
1454 impl TypePath for Type {
1455 fn type_path() -> &'static str {
1456 "Long"
1458 }
1459
1460 fn short_type_path() -> &'static str {
1461 "Short"
1462 }
1463 }
1464
1465 assert_type_paths! {
1466 u8 => "u8", "u8",
1467 Type => "Long", "Short",
1468 &Type => "&Long", "&Short",
1469 [Type] => "[Long]", "[Short]",
1470 &[Type] => "&[Long]", "&[Short]",
1471 [Type; 0] => "[Long; 0]", "[Short; 0]",
1472 [Type; 100] => "[Long; 100]", "[Short; 100]",
1473 () => "()", "()",
1474 (Type,) => "(Long,)", "(Short,)",
1475 (Type, Type) => "(Long, Long)", "(Short, Short)",
1476 (Type, Type, Type) => "(Long, Long, Long)", "(Short, Short, Short)",
1477 Cow<'static, Type> => "alloc::borrow::Cow<Long>", "Cow<Short>",
1478 }
1479 }
1480
1481 #[test]
1482 fn reflect_type_info() {
1483 let info = i32::type_info();
1485 assert_eq!(i32::type_path(), info.type_path());
1486 assert_eq!(TypeId::of::<i32>(), info.type_id());
1487
1488 assert_eq!(
1490 TypeId::of::<dyn Reflect>(),
1491 <dyn Reflect as Typed>::type_info().type_id()
1492 );
1493
1494 let value: &dyn Reflect = &123_i32;
1496 let info = value.get_represented_type_info().unwrap();
1497 assert!(info.is::<i32>());
1498
1499 #[derive(Reflect)]
1501 struct MyStruct {
1502 foo: i32,
1503 bar: usize,
1504 }
1505
1506 let info = MyStruct::type_info();
1507 if let TypeInfo::Struct(info) = info {
1508 assert!(info.is::<MyStruct>());
1509 assert_eq!(MyStruct::type_path(), info.type_path());
1510 assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
1511 assert_eq!(TypeId::of::<i32>(), info.field("foo").unwrap().type_id());
1512 assert!(info.field("foo").unwrap().is::<i32>());
1513 assert_eq!("foo", info.field("foo").unwrap().name());
1514 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
1515 } else {
1516 panic!("Expected `TypeInfo::Struct`");
1517 }
1518
1519 let value: &dyn Reflect = &MyStruct { foo: 123, bar: 321 };
1520 let info = value.get_represented_type_info().unwrap();
1521 assert!(info.is::<MyStruct>());
1522
1523 #[derive(Reflect)]
1525 struct MyGenericStruct<T> {
1526 foo: T,
1527 bar: usize,
1528 }
1529
1530 let info = <MyGenericStruct<i32>>::type_info();
1531 if let TypeInfo::Struct(info) = info {
1532 assert!(info.is::<MyGenericStruct<i32>>());
1533 assert_eq!(MyGenericStruct::<i32>::type_path(), info.type_path());
1534 assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
1535 assert_eq!("foo", info.field("foo").unwrap().name());
1536 assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
1537 } else {
1538 panic!("Expected `TypeInfo::Struct`");
1539 }
1540
1541 let value: &dyn Reflect = &MyGenericStruct {
1542 foo: String::from("Hello!"),
1543 bar: 321,
1544 };
1545 let info = value.get_represented_type_info().unwrap();
1546 assert!(info.is::<MyGenericStruct<String>>());
1547
1548 #[derive(Reflect)]
1550 struct MyTupleStruct(usize, i32, MyStruct);
1551
1552 let info = MyTupleStruct::type_info();
1553 if let TypeInfo::TupleStruct(info) = info {
1554 assert!(info.is::<MyTupleStruct>());
1555 assert_eq!(MyTupleStruct::type_path(), info.type_path());
1556 assert_eq!(i32::type_path(), info.field_at(1).unwrap().type_path());
1557 assert!(info.field_at(1).unwrap().is::<i32>());
1558 } else {
1559 panic!("Expected `TypeInfo::TupleStruct`");
1560 }
1561
1562 type MyTuple = (u32, f32, String);
1564
1565 let info = MyTuple::type_info();
1566 if let TypeInfo::Tuple(info) = info {
1567 assert!(info.is::<MyTuple>());
1568 assert_eq!(MyTuple::type_path(), info.type_path());
1569 assert_eq!(f32::type_path(), info.field_at(1).unwrap().type_path());
1570 } else {
1571 panic!("Expected `TypeInfo::Tuple`");
1572 }
1573
1574 let value: &dyn Reflect = &(123_u32, 1.23_f32, String::from("Hello!"));
1575 let info = value.get_represented_type_info().unwrap();
1576 assert!(info.is::<MyTuple>());
1577
1578 type MyList = Vec<usize>;
1580
1581 let info = MyList::type_info();
1582 if let TypeInfo::List(info) = info {
1583 assert!(info.is::<MyList>());
1584 assert!(info.item_is::<usize>());
1585 assert_eq!(MyList::type_path(), info.type_path());
1586 assert_eq!(usize::type_path(), info.item_type_path_table().path());
1587 } else {
1588 panic!("Expected `TypeInfo::List`");
1589 }
1590
1591 let value: &dyn Reflect = &vec![123_usize];
1592 let info = value.get_represented_type_info().unwrap();
1593 assert!(info.is::<MyList>());
1594
1595 #[cfg(feature = "smallvec")]
1597 {
1598 type MySmallVec = smallvec::SmallVec<[String; 2]>;
1599
1600 let info = MySmallVec::type_info();
1601 if let TypeInfo::List(info) = info {
1602 assert!(info.is::<MySmallVec>());
1603 assert!(info.item_is::<String>());
1604 assert_eq!(MySmallVec::type_path(), info.type_path());
1605 assert_eq!(String::type_path(), info.item_type_path_table().path());
1606 } else {
1607 panic!("Expected `TypeInfo::List`");
1608 }
1609
1610 let value: MySmallVec = smallvec::smallvec![String::default(); 2];
1611 let value: &dyn Reflect = &value;
1612 let info = value.get_represented_type_info().unwrap();
1613 assert!(info.is::<MySmallVec>());
1614 }
1615
1616 type MyArray = [usize; 3];
1618
1619 let info = MyArray::type_info();
1620 if let TypeInfo::Array(info) = info {
1621 assert!(info.is::<MyArray>());
1622 assert!(info.item_is::<usize>());
1623 assert_eq!(MyArray::type_path(), info.type_path());
1624 assert_eq!(usize::type_path(), info.item_type_path_table().path());
1625 assert_eq!(3, info.capacity());
1626 } else {
1627 panic!("Expected `TypeInfo::Array`");
1628 }
1629
1630 let value: &dyn Reflect = &[1usize, 2usize, 3usize];
1631 let info = value.get_represented_type_info().unwrap();
1632 assert!(info.is::<MyArray>());
1633
1634 type MyCowStr = Cow<'static, str>;
1636
1637 let info = MyCowStr::type_info();
1638 if let TypeInfo::Value(info) = info {
1639 assert!(info.is::<MyCowStr>());
1640 assert_eq!(std::any::type_name::<MyCowStr>(), info.type_path());
1641 } else {
1642 panic!("Expected `TypeInfo::Value`");
1643 }
1644
1645 let value: &dyn Reflect = &Cow::<'static, str>::Owned("Hello!".to_string());
1646 let info = value.get_represented_type_info().unwrap();
1647 assert!(info.is::<MyCowStr>());
1648
1649 type MyCowSlice = Cow<'static, [u8]>;
1651
1652 let info = MyCowSlice::type_info();
1653 if let TypeInfo::List(info) = info {
1654 assert!(info.is::<MyCowSlice>());
1655 assert!(info.item_is::<u8>());
1656 assert_eq!(std::any::type_name::<MyCowSlice>(), info.type_path());
1657 assert_eq!(
1658 std::any::type_name::<u8>(),
1659 info.item_type_path_table().path()
1660 );
1661 } else {
1662 panic!("Expected `TypeInfo::List`");
1663 }
1664
1665 let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]);
1666 let info = value.get_represented_type_info().unwrap();
1667 assert!(info.is::<MyCowSlice>());
1668
1669 type MyMap = HashMap<usize, f32>;
1671
1672 let info = MyMap::type_info();
1673 if let TypeInfo::Map(info) = info {
1674 assert!(info.is::<MyMap>());
1675 assert!(info.key_is::<usize>());
1676 assert!(info.value_is::<f32>());
1677 assert_eq!(MyMap::type_path(), info.type_path());
1678 assert_eq!(usize::type_path(), info.key_type_path_table().path());
1679 assert_eq!(f32::type_path(), info.value_type_path_table().path());
1680 } else {
1681 panic!("Expected `TypeInfo::Map`");
1682 }
1683
1684 let value: &dyn Reflect = &MyMap::new();
1685 let info = value.get_represented_type_info().unwrap();
1686 assert!(info.is::<MyMap>());
1687
1688 type MyValue = String;
1690
1691 let info = MyValue::type_info();
1692 if let TypeInfo::Value(info) = info {
1693 assert!(info.is::<MyValue>());
1694 assert_eq!(MyValue::type_path(), info.type_path());
1695 } else {
1696 panic!("Expected `TypeInfo::Value`");
1697 }
1698
1699 let value: &dyn Reflect = &String::from("Hello!");
1700 let info = value.get_represented_type_info().unwrap();
1701 assert!(info.is::<MyValue>());
1702 }
1703
1704 #[test]
1705 fn should_permit_higher_ranked_lifetimes() {
1706 #[derive(Reflect)]
1707 #[reflect(from_reflect = false)]
1708 struct TestStruct {
1709 #[reflect(ignore)]
1710 _hrl: for<'a> fn(&'a str) -> &'a str,
1711 }
1712
1713 impl Default for TestStruct {
1714 fn default() -> Self {
1715 TestStruct {
1716 _hrl: |input| input,
1717 }
1718 }
1719 }
1720
1721 fn get_type_registration<T: GetTypeRegistration>() {}
1722 get_type_registration::<TestStruct>();
1723 }
1724
1725 #[test]
1726 fn should_permit_valid_represented_type_for_dynamic() {
1727 let type_info = <[i32; 2] as Typed>::type_info();
1728 let mut dynamic_array = [123; 2].clone_dynamic();
1729 dynamic_array.set_represented_type(Some(type_info));
1730 }
1731
1732 #[test]
1733 #[should_panic(expected = "expected TypeInfo::Array but received")]
1734 fn should_prohibit_invalid_represented_type_for_dynamic() {
1735 let type_info = <(i32, i32) as Typed>::type_info();
1736 let mut dynamic_array = [123; 2].clone_dynamic();
1737 dynamic_array.set_represented_type(Some(type_info));
1738 }
1739
1740 #[cfg(feature = "documentation")]
1741 mod docstrings {
1742 use super::*;
1743
1744 #[test]
1745 fn should_not_contain_docs() {
1746 #[derive(Reflect)]
1749 struct SomeStruct;
1750
1751 let info = <SomeStruct as Typed>::type_info();
1752 assert_eq!(None, info.docs());
1753
1754 #[derive(Reflect)]
1759 struct SomeOtherStruct;
1760
1761 let info = <SomeOtherStruct as Typed>::type_info();
1762 assert_eq!(None, info.docs());
1763 }
1764
1765 #[test]
1766 fn should_contain_docs() {
1767 #[derive(Reflect)]
1775 struct SomeStruct;
1776
1777 let info = <SomeStruct as Typed>::type_info();
1778 assert_eq!(
1779 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 ```"),
1780 info.docs()
1781 );
1782
1783 #[doc = "The compiler automatically converts `///`-style comments into `#[doc]` attributes."]
1784 #[doc = "Of course, you _could_ use the attribute directly if you wanted to."]
1785 #[doc = "Both will be reflected."]
1786 #[derive(Reflect)]
1787 struct SomeOtherStruct;
1788
1789 let info = <SomeOtherStruct as Typed>::type_info();
1790 assert_eq!(
1791 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."),
1792 info.docs()
1793 );
1794
1795 #[derive(Reflect)]
1797 struct SomeTupleStruct(usize);
1798
1799 let info = <SomeTupleStruct as Typed>::type_info();
1800 assert_eq!(Some(" Some tuple struct."), info.docs());
1801
1802 #[derive(Reflect)]
1804 enum SomeEnum {
1805 Foo,
1806 }
1807
1808 let info = <SomeEnum as Typed>::type_info();
1809 assert_eq!(Some(" Some enum."), info.docs());
1810
1811 #[derive(Clone)]
1812 struct SomePrimitive;
1813 impl_reflect_value!(
1814 (in bevy_reflect::tests) SomePrimitive
1816 );
1817
1818 let info = <SomePrimitive as Typed>::type_info();
1819 assert_eq!(
1820 Some(" Some primitive for which we have attributed custom documentation."),
1821 info.docs()
1822 );
1823 }
1824
1825 #[test]
1826 fn fields_should_contain_docs() {
1827 #[derive(Reflect)]
1828 struct SomeStruct {
1829 name: String,
1831 index: usize,
1833 data: Vec<i32>,
1835 }
1836
1837 let info = <SomeStruct as Typed>::type_info();
1838 if let TypeInfo::Struct(info) = info {
1839 let mut fields = info.iter();
1840 assert_eq!(Some(" The name"), fields.next().unwrap().docs());
1841 assert_eq!(Some(" The index"), fields.next().unwrap().docs());
1842 assert_eq!(None, fields.next().unwrap().docs());
1843 } else {
1844 panic!("expected struct info");
1845 }
1846 }
1847
1848 #[test]
1849 fn variants_should_contain_docs() {
1850 #[derive(Reflect)]
1851 enum SomeEnum {
1852 Nothing,
1854 A(
1856 usize,
1858 ),
1859 B {
1861 name: String,
1863 },
1864 }
1865
1866 let info = <SomeEnum as Typed>::type_info();
1867 if let TypeInfo::Enum(info) = info {
1868 let mut variants = info.iter();
1869 assert_eq!(None, variants.next().unwrap().docs());
1870
1871 let variant = variants.next().unwrap();
1872 assert_eq!(Some(" Option A"), variant.docs());
1873 if let VariantInfo::Tuple(variant) = variant {
1874 let field = variant.field_at(0).unwrap();
1875 assert_eq!(Some(" Index"), field.docs());
1876 } else {
1877 panic!("expected tuple variant")
1878 }
1879
1880 let variant = variants.next().unwrap();
1881 assert_eq!(Some(" Option B"), variant.docs());
1882 if let VariantInfo::Struct(variant) = variant {
1883 let field = variant.field_at(0).unwrap();
1884 assert_eq!(Some(" Name"), field.docs());
1885 } else {
1886 panic!("expected struct variant")
1887 }
1888 } else {
1889 panic!("expected enum info");
1890 }
1891 }
1892 }
1893
1894 #[test]
1895 fn into_reflect() {
1896 trait TestTrait: Reflect {}
1897
1898 #[derive(Reflect)]
1899 struct TestStruct;
1900
1901 impl TestTrait for TestStruct {}
1902
1903 let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
1904
1905 let _ = trait_object.into_reflect();
1907 }
1908
1909 #[test]
1910 fn as_reflect() {
1911 trait TestTrait: Reflect {}
1912
1913 #[derive(Reflect)]
1914 struct TestStruct;
1915
1916 impl TestTrait for TestStruct {}
1917
1918 let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
1919
1920 let _ = trait_object.as_reflect();
1922 }
1923
1924 #[test]
1925 fn should_reflect_debug() {
1926 #[derive(Reflect)]
1927 struct Test {
1928 value: usize,
1929 list: Vec<String>,
1930 array: [f32; 3],
1931 map: HashMap<i32, f32>,
1932 a_struct: SomeStruct,
1933 a_tuple_struct: SomeTupleStruct,
1934 enum_unit: SomeEnum,
1935 enum_tuple: SomeEnum,
1936 enum_struct: SomeEnum,
1937 custom: CustomDebug,
1938 #[reflect(ignore)]
1939 #[allow(dead_code)]
1940 ignored: isize,
1941 }
1942
1943 #[derive(Reflect)]
1944 struct SomeStruct {
1945 foo: String,
1946 }
1947
1948 #[derive(Reflect)]
1949 enum SomeEnum {
1950 A,
1951 B(usize),
1952 C { value: i32 },
1953 }
1954
1955 #[derive(Reflect)]
1956 struct SomeTupleStruct(String);
1957
1958 #[derive(Reflect)]
1959 #[reflect(Debug)]
1960 struct CustomDebug;
1961 impl Debug for CustomDebug {
1962 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1963 f.write_str("Cool debug!")
1964 }
1965 }
1966
1967 let mut map = HashMap::new();
1968 map.insert(123, 1.23);
1969
1970 let test = Test {
1971 value: 123,
1972 list: vec![String::from("A"), String::from("B"), String::from("C")],
1973 array: [1.0, 2.0, 3.0],
1974 map,
1975 a_struct: SomeStruct {
1976 foo: String::from("A Struct!"),
1977 },
1978 a_tuple_struct: SomeTupleStruct(String::from("A Tuple Struct!")),
1979 enum_unit: SomeEnum::A,
1980 enum_tuple: SomeEnum::B(123),
1981 enum_struct: SomeEnum::C { value: 321 },
1982 custom: CustomDebug,
1983 ignored: 321,
1984 };
1985
1986 let reflected: &dyn Reflect = &test;
1987 let expected = r#"
1988bevy_reflect::tests::Test {
1989 value: 123,
1990 list: [
1991 "A",
1992 "B",
1993 "C",
1994 ],
1995 array: [
1996 1.0,
1997 2.0,
1998 3.0,
1999 ],
2000 map: {
2001 123: 1.23,
2002 },
2003 a_struct: bevy_reflect::tests::SomeStruct {
2004 foo: "A Struct!",
2005 },
2006 a_tuple_struct: bevy_reflect::tests::SomeTupleStruct(
2007 "A Tuple Struct!",
2008 ),
2009 enum_unit: A,
2010 enum_tuple: B(
2011 123,
2012 ),
2013 enum_struct: C {
2014 value: 321,
2015 },
2016 custom: Cool debug!,
2017}"#;
2018
2019 assert_eq!(expected, format!("\n{reflected:#?}"));
2020 }
2021
2022 #[test]
2023 fn multiple_reflect_lists() {
2024 #[derive(Hash, PartialEq, Reflect)]
2025 #[reflect(Debug, Hash)]
2026 #[reflect(PartialEq)]
2027 struct Foo(i32);
2028
2029 impl Debug for Foo {
2030 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2031 write!(f, "Foo")
2032 }
2033 }
2034
2035 let foo = Foo(123);
2036 let foo: &dyn Reflect = &foo;
2037
2038 assert!(foo.reflect_hash().is_some());
2039 assert_eq!(Some(true), foo.reflect_partial_eq(foo));
2040 assert_eq!("Foo".to_string(), format!("{foo:?}"));
2041 }
2042
2043 #[test]
2044 fn multiple_reflect_value_lists() {
2045 #[derive(Clone, Hash, PartialEq, Reflect)]
2046 #[reflect_value(Debug, Hash)]
2047 #[reflect_value(PartialEq)]
2048 struct Foo(i32);
2049
2050 impl Debug for Foo {
2051 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2052 write!(f, "Foo")
2053 }
2054 }
2055
2056 let foo = Foo(123);
2057 let foo: &dyn Reflect = &foo;
2058
2059 assert!(foo.reflect_hash().is_some());
2060 assert_eq!(Some(true), foo.reflect_partial_eq(foo));
2061 assert_eq!("Foo".to_string(), format!("{foo:?}"));
2062 }
2063
2064 #[test]
2065 fn custom_debug_function() {
2066 #[derive(Reflect)]
2067 #[reflect(Debug(custom_debug))]
2068 struct Foo {
2069 a: u32,
2070 }
2071
2072 fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> std::fmt::Result {
2073 write!(f, "123")
2074 }
2075
2076 let foo = Foo { a: 1 };
2077 let foo: &dyn Reflect = &foo;
2078
2079 assert_eq!("123", format!("{:?}", foo));
2080 }
2081
2082 #[test]
2083 fn should_allow_custom_where() {
2084 #[derive(Reflect)]
2085 #[reflect(where T: Default)]
2086 struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2087
2088 #[derive(Default, TypePath)]
2089 struct Bar;
2090
2091 #[derive(TypePath)]
2092 struct Baz;
2093
2094 assert_impl_all!(Foo<Bar>: Reflect);
2095 assert_not_impl_all!(Foo<Baz>: Reflect);
2096 }
2097
2098 #[test]
2099 fn should_allow_empty_custom_where() {
2100 #[derive(Reflect)]
2101 #[reflect(where)]
2102 struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2103
2104 #[derive(TypePath)]
2105 struct Bar;
2106
2107 assert_impl_all!(Foo<Bar>: Reflect);
2108 }
2109
2110 #[test]
2111 fn should_allow_multiple_custom_where() {
2112 #[derive(Reflect)]
2113 #[reflect(where T: Default)]
2114 #[reflect(where U: std::ops::Add<T>)]
2115 struct Foo<T, U>(T, U);
2116
2117 #[derive(Reflect)]
2118 struct Baz {
2119 a: Foo<i32, i32>,
2120 b: Foo<u32, u32>,
2121 }
2122
2123 assert_impl_all!(Foo<i32, i32>: Reflect);
2124 assert_not_impl_all!(Foo<i32, usize>: Reflect);
2125 }
2126
2127 #[test]
2128 fn should_allow_custom_where_with_assoc_type() {
2129 trait Trait {
2130 type Assoc;
2131 }
2132
2133 #[derive(Reflect)]
2135 #[reflect(where T::Assoc: core::fmt::Display)]
2136 struct Foo<T: Trait>(T::Assoc);
2137
2138 #[derive(TypePath)]
2139 struct Bar;
2140
2141 impl Trait for Bar {
2142 type Assoc = usize;
2143 }
2144
2145 #[derive(TypePath)]
2146 struct Baz;
2147
2148 impl Trait for Baz {
2149 type Assoc = (f32, f32);
2150 }
2151
2152 assert_impl_all!(Foo<Bar>: Reflect);
2153 assert_not_impl_all!(Foo<Baz>: Reflect);
2154 }
2155
2156 #[test]
2157 fn recursive_typed_storage_does_not_hang() {
2158 #[derive(Reflect)]
2159 struct Recurse<T>(T);
2160
2161 let _ = <Recurse<Recurse<()>> as Typed>::type_info();
2162 let _ = <Recurse<Recurse<()>> as TypePath>::type_path();
2163
2164 #[derive(Reflect)]
2165 #[reflect(no_field_bounds)]
2166 struct SelfRecurse {
2167 recurse: Vec<SelfRecurse>,
2168 }
2169
2170 let _ = <SelfRecurse as Typed>::type_info();
2171 let _ = <SelfRecurse as TypePath>::type_path();
2172
2173 #[derive(Reflect)]
2174 #[reflect(no_field_bounds)]
2175 enum RecurseA {
2176 Recurse(RecurseB),
2177 }
2178
2179 #[derive(Reflect)]
2180 struct RecurseB {
2182 vector: Vec<RecurseA>,
2183 }
2184
2185 let _ = <RecurseA as Typed>::type_info();
2186 let _ = <RecurseA as TypePath>::type_path();
2187 let _ = <RecurseB as Typed>::type_info();
2188 let _ = <RecurseB as TypePath>::type_path();
2189 }
2190
2191 #[test]
2192 fn recursive_registration_does_not_hang() {
2193 #[derive(Reflect)]
2194 struct Recurse<T>(T);
2195
2196 let mut registry = TypeRegistry::empty();
2197
2198 registry.register::<Recurse<Recurse<()>>>();
2199
2200 #[derive(Reflect)]
2201 #[reflect(no_field_bounds)]
2202 struct SelfRecurse {
2203 recurse: Vec<SelfRecurse>,
2204 }
2205
2206 registry.register::<SelfRecurse>();
2207
2208 #[derive(Reflect)]
2209 #[reflect(no_field_bounds)]
2210 enum RecurseA {
2211 Recurse(RecurseB),
2212 }
2213
2214 #[derive(Reflect)]
2215 struct RecurseB {
2216 vector: Vec<RecurseA>,
2217 }
2218
2219 registry.register::<RecurseA>();
2220 assert!(registry.contains(TypeId::of::<RecurseA>()));
2221 assert!(registry.contains(TypeId::of::<RecurseB>()));
2222 }
2223
2224 #[test]
2225 fn can_opt_out_type_path() {
2226 #[derive(Reflect)]
2227 #[reflect(type_path = false)]
2228 struct Foo<T> {
2229 #[reflect(ignore)]
2230 _marker: PhantomData<T>,
2231 }
2232
2233 struct NotTypePath;
2234
2235 impl<T: 'static> TypePath for Foo<T> {
2236 fn type_path() -> &'static str {
2237 std::any::type_name::<Self>()
2238 }
2239
2240 fn short_type_path() -> &'static str {
2241 static CELL: GenericTypePathCell = GenericTypePathCell::new();
2242 CELL.get_or_insert::<Self, _>(|| {
2243 bevy_utils::get_short_name(std::any::type_name::<Self>())
2244 })
2245 }
2246
2247 fn type_ident() -> Option<&'static str> {
2248 Some("Foo")
2249 }
2250
2251 fn crate_name() -> Option<&'static str> {
2252 Some("bevy_reflect")
2253 }
2254
2255 fn module_path() -> Option<&'static str> {
2256 Some("bevy_reflect::tests")
2257 }
2258 }
2259
2260 let path = <Foo<NotTypePath> as TypePath>::type_path();
2262 assert_eq!("bevy_reflect::tests::can_opt_out_type_path::Foo<bevy_reflect::tests::can_opt_out_type_path::NotTypePath>", path);
2263
2264 let mut registry = TypeRegistry::default();
2266 registry.register::<Foo<NotTypePath>>();
2267
2268 let registration = registry.get(TypeId::of::<Foo<NotTypePath>>()).unwrap();
2269 assert_eq!(
2270 "Foo<NotTypePath>",
2271 registration.type_info().type_path_table().short_path()
2272 );
2273 }
2274
2275 #[test]
2276 fn dynamic_types_debug_format() {
2277 #[derive(Debug, Reflect)]
2278 struct TestTupleStruct(u32);
2279
2280 #[derive(Debug, Reflect)]
2281 enum TestEnum {
2282 A(u32),
2283 B,
2284 }
2285
2286 #[derive(Debug, Reflect)]
2287 struct TestStruct {
2289 tuple: (u32, u32),
2291 tuple_struct: TestTupleStruct,
2293 list: Vec<u32>,
2295 array: [u32; 3],
2297 e: TestEnum,
2299 map: HashMap<u32, u32>,
2301 value: u32,
2303 }
2304 let mut map = HashMap::new();
2305 map.insert(9, 10);
2306 let mut test_struct = TestStruct {
2307 tuple: (0, 1),
2308 list: vec![2, 3, 4],
2309 array: [5, 6, 7],
2310 tuple_struct: TestTupleStruct(8),
2311 e: TestEnum::A(11),
2312 map,
2313 value: 12,
2314 }
2315 .clone_value();
2316 let test_struct = test_struct.downcast_mut::<DynamicStruct>().unwrap();
2317
2318 let mut test_unknown_struct = DynamicStruct::default();
2320 test_unknown_struct.insert("a", 13);
2321 test_struct.insert("unknown_struct", test_unknown_struct);
2322 let mut test_unknown_tuple_struct = DynamicTupleStruct::default();
2324 test_unknown_tuple_struct.insert(14);
2325 test_struct.insert("unknown_tuplestruct", test_unknown_tuple_struct);
2326 assert_eq!(
2327 format!("{:?}", test_struct),
2328 "DynamicStruct(bevy_reflect::tests::TestStruct { \
2329 tuple: DynamicTuple((0, 1)), \
2330 tuple_struct: DynamicTupleStruct(bevy_reflect::tests::TestTupleStruct(8)), \
2331 list: DynamicList([2, 3, 4]), \
2332 array: DynamicArray([5, 6, 7]), \
2333 e: DynamicEnum(A(11)), \
2334 map: DynamicMap({9: 10}), \
2335 value: 12, \
2336 unknown_struct: DynamicStruct(_ { a: 13 }), \
2337 unknown_tuplestruct: DynamicTupleStruct(_(14)) \
2338 })"
2339 );
2340 }
2341
2342 #[test]
2343 fn assert_impl_reflect_macro_on_all() {
2344 struct Struct {
2345 foo: (),
2346 }
2347 struct TupleStruct(());
2348 enum Enum {
2349 Foo { foo: () },
2350 Bar(()),
2351 }
2352
2353 impl_reflect!(
2354 #[type_path = "my_crate::foo"]
2355 struct Struct {
2356 foo: (),
2357 }
2358 );
2359
2360 impl_reflect!(
2361 #[type_path = "my_crate::foo"]
2362 struct TupleStruct(());
2363 );
2364
2365 impl_reflect!(
2366 #[type_path = "my_crate::foo"]
2367 enum Enum {
2368 Foo { foo: () },
2369 Bar(()),
2370 }
2371 );
2372
2373 assert_impl_all!(Struct: Reflect);
2374 assert_impl_all!(TupleStruct: Reflect);
2375 assert_impl_all!(Enum: Reflect);
2376 }
2377
2378 #[cfg(feature = "glam")]
2379 mod glam {
2380 use super::*;
2381 use ::glam::{quat, vec3, Quat, Vec3};
2382
2383 #[test]
2384 fn quat_serialization() {
2385 let q = quat(1.0, 2.0, 3.0, 4.0);
2386
2387 let mut registry = TypeRegistry::default();
2388 registry.register::<f32>();
2389 registry.register::<Quat>();
2390
2391 let ser = ReflectSerializer::new(&q, ®istry);
2392
2393 let config = PrettyConfig::default()
2394 .new_line(String::from("\n"))
2395 .indentor(String::from(" "));
2396 let output = to_string_pretty(&ser, config).unwrap();
2397 let expected = r#"
2398{
2399 "glam::Quat": (
2400 x: 1.0,
2401 y: 2.0,
2402 z: 3.0,
2403 w: 4.0,
2404 ),
2405}"#;
2406
2407 assert_eq!(expected, format!("\n{output}"));
2408 }
2409
2410 #[test]
2411 fn quat_deserialization() {
2412 let data = r#"
2413{
2414 "glam::Quat": (
2415 x: 1.0,
2416 y: 2.0,
2417 z: 3.0,
2418 w: 4.0,
2419 ),
2420}"#;
2421
2422 let mut registry = TypeRegistry::default();
2423 registry.register::<Quat>();
2424 registry.register::<f32>();
2425
2426 let de = ReflectDeserializer::new(®istry);
2427
2428 let mut deserializer =
2429 Deserializer::from_str(data).expect("Failed to acquire deserializer");
2430
2431 let dynamic_struct = de
2432 .deserialize(&mut deserializer)
2433 .expect("Failed to deserialize");
2434
2435 let mut result = Quat::default();
2436
2437 result.apply(&*dynamic_struct);
2438
2439 assert_eq!(result, quat(1.0, 2.0, 3.0, 4.0));
2440 }
2441
2442 #[test]
2443 fn vec3_serialization() {
2444 let v = vec3(12.0, 3.0, -6.9);
2445
2446 let mut registry = TypeRegistry::default();
2447 registry.register::<f32>();
2448 registry.register::<Vec3>();
2449
2450 let ser = ReflectSerializer::new(&v, ®istry);
2451
2452 let config = PrettyConfig::default()
2453 .new_line(String::from("\n"))
2454 .indentor(String::from(" "));
2455 let output = to_string_pretty(&ser, config).unwrap();
2456 let expected = r#"
2457{
2458 "glam::Vec3": (
2459 x: 12.0,
2460 y: 3.0,
2461 z: -6.9,
2462 ),
2463}"#;
2464
2465 assert_eq!(expected, format!("\n{output}"));
2466 }
2467
2468 #[test]
2469 fn vec3_deserialization() {
2470 let data = r#"
2471{
2472 "glam::Vec3": (
2473 x: 12.0,
2474 y: 3.0,
2475 z: -6.9,
2476 ),
2477}"#;
2478
2479 let mut registry = TypeRegistry::default();
2480 registry.add_registration(Vec3::get_type_registration());
2481 registry.add_registration(f32::get_type_registration());
2482
2483 let de = ReflectDeserializer::new(®istry);
2484
2485 let mut deserializer =
2486 Deserializer::from_str(data).expect("Failed to acquire deserializer");
2487
2488 let dynamic_struct = de
2489 .deserialize(&mut deserializer)
2490 .expect("Failed to deserialize");
2491
2492 let mut result = Vec3::default();
2493
2494 result.apply(&*dynamic_struct);
2495
2496 assert_eq!(result, vec3(12.0, 3.0, -6.9));
2497 }
2498
2499 #[test]
2500 fn vec3_field_access() {
2501 let mut v = vec3(1.0, 2.0, 3.0);
2502
2503 assert_eq!(*v.get_field::<f32>("x").unwrap(), 1.0);
2504
2505 *v.get_field_mut::<f32>("y").unwrap() = 6.0;
2506
2507 assert_eq!(v.y, 6.0);
2508 }
2509
2510 #[test]
2511 fn vec3_path_access() {
2512 let mut v = vec3(1.0, 2.0, 3.0);
2513
2514 assert_eq!(
2515 *v.reflect_path("x").unwrap().downcast_ref::<f32>().unwrap(),
2516 1.0
2517 );
2518
2519 *v.reflect_path_mut("y")
2520 .unwrap()
2521 .downcast_mut::<f32>()
2522 .unwrap() = 6.0;
2523
2524 assert_eq!(v.y, 6.0);
2525 }
2526
2527 #[test]
2528 fn vec3_apply_dynamic() {
2529 let mut v = vec3(3.0, 3.0, 3.0);
2530
2531 let mut d = DynamicStruct::default();
2532 d.insert("x", 4.0f32);
2533 d.insert("y", 2.0f32);
2534 d.insert("z", 1.0f32);
2535
2536 v.apply(&d);
2537
2538 assert_eq!(v, vec3(4.0, 2.0, 1.0));
2539 }
2540 }
2541}