Fix debug printing for dynamic types (#10740)
# Objective
Printing `DynamicStruct` with a debug format does not show the contained
type anymore. For instance, in `examples/reflection/reflection.rs`,
adding `dbg!(&reflect_value);` to line 96 will print:
```rust
[examples/reflection/reflection.rs:96] &reflect_value = DynamicStruct(bevy_reflect::DynamicStruct {
    a: 4,
    nested: DynamicStruct(bevy_reflect::DynamicStruct {
        b: 8,
    }),
})
```
## Solution
Show the represented type instead (`reflection::Foo` and
`reflection::Bar` in this case):
```rust
[examples/reflection/reflection.rs:96] &reflect_value = DynamicStruct(reflection::Foo {
    a: 4,
    nested: DynamicStruct(reflection::Bar {
        b: 8,
    }),
})
```
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
			
			
This commit is contained in:
		
							parent
							
								
									9c8576996f
								
							
						
					
					
						commit
						55402bdf2e
					
				| @ -5,7 +5,7 @@ use crate::{ | |||||||
| use bevy_reflect_derive::impl_type_path; | use bevy_reflect_derive::impl_type_path; | ||||||
| use std::{ | use std::{ | ||||||
|     any::{Any, TypeId}, |     any::{Any, TypeId}, | ||||||
|     fmt::Debug, |     fmt::{Debug, Formatter}, | ||||||
|     hash::{Hash, Hasher}, |     hash::{Hash, Hasher}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -301,6 +301,12 @@ impl Reflect for DynamicArray { | |||||||
|     fn is_dynamic(&self) -> bool { |     fn is_dynamic(&self) -> bool { | ||||||
|         true |         true | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         write!(f, "DynamicArray(")?; | ||||||
|  |         array_debug(self, f)?; | ||||||
|  |         write!(f, ")") | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Array for DynamicArray { | impl Array for DynamicArray { | ||||||
|  | |||||||
| @ -1927,6 +1927,73 @@ bevy_reflect::tests::Test { | |||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn dynamic_types_debug_format() { | ||||||
|  |         #[derive(Debug, Reflect)] | ||||||
|  |         struct TestTupleStruct(u32); | ||||||
|  | 
 | ||||||
|  |         #[derive(Debug, Reflect)] | ||||||
|  |         enum TestEnum { | ||||||
|  |             A(u32), | ||||||
|  |             B, | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         #[derive(Debug, Reflect)] | ||||||
|  |         // test DynamicStruct
 | ||||||
|  |         struct TestStruct { | ||||||
|  |             // test DynamicTuple
 | ||||||
|  |             tuple: (u32, u32), | ||||||
|  |             // test DynamicTupleStruct
 | ||||||
|  |             tuple_struct: TestTupleStruct, | ||||||
|  |             // test DynamicList
 | ||||||
|  |             list: Vec<u32>, | ||||||
|  |             // test DynamicArray
 | ||||||
|  |             array: [u32; 3], | ||||||
|  |             // test DynamicEnum
 | ||||||
|  |             e: TestEnum, | ||||||
|  |             // test DynamicMap
 | ||||||
|  |             map: HashMap<u32, u32>, | ||||||
|  |             // test reflected value
 | ||||||
|  |             value: u32, | ||||||
|  |         } | ||||||
|  |         let mut map = HashMap::new(); | ||||||
|  |         map.insert(9, 10); | ||||||
|  |         let mut test_struct = TestStruct { | ||||||
|  |             tuple: (0, 1), | ||||||
|  |             list: vec![2, 3, 4], | ||||||
|  |             array: [5, 6, 7], | ||||||
|  |             tuple_struct: TestTupleStruct(8), | ||||||
|  |             e: TestEnum::A(11), | ||||||
|  |             map, | ||||||
|  |             value: 12, | ||||||
|  |         } | ||||||
|  |         .clone_value(); | ||||||
|  |         let test_struct = test_struct.downcast_mut::<DynamicStruct>().unwrap(); | ||||||
|  | 
 | ||||||
|  |         // test unknown DynamicStruct
 | ||||||
|  |         let mut test_unknown_struct = DynamicStruct::default(); | ||||||
|  |         test_unknown_struct.insert("a", 13); | ||||||
|  |         test_struct.insert("unknown_struct", test_unknown_struct); | ||||||
|  |         // test unknown DynamicTupleStruct
 | ||||||
|  |         let mut test_unknown_tuple_struct = DynamicTupleStruct::default(); | ||||||
|  |         test_unknown_tuple_struct.insert(14); | ||||||
|  |         test_struct.insert("unknown_tuplestruct", test_unknown_tuple_struct); | ||||||
|  |         assert_eq!( | ||||||
|  |             format!("{:?}", test_struct), | ||||||
|  |             "DynamicStruct(bevy_reflect::tests::TestStruct { \ | ||||||
|  |                 tuple: DynamicTuple((0, 1)), \ | ||||||
|  |                 tuple_struct: DynamicTupleStruct(bevy_reflect::tests::TestTupleStruct(8)), \ | ||||||
|  |                 list: DynamicList([2, 3, 4]), \ | ||||||
|  |                 array: DynamicArray([5, 6, 7]), \ | ||||||
|  |                 e: DynamicEnum(A(11)), \ | ||||||
|  |                 map: DynamicMap({9: 10}), \ | ||||||
|  |                 value: 12, \ | ||||||
|  |                 unknown_struct: DynamicStruct(_ { a: 13 }), \ | ||||||
|  |                 unknown_tuplestruct: DynamicTupleStruct(_(14)) \ | ||||||
|  |             })" | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     #[cfg(feature = "glam")] |     #[cfg(feature = "glam")] | ||||||
|     mod glam { |     mod glam { | ||||||
|         use super::*; |         use super::*; | ||||||
|  | |||||||
| @ -543,7 +543,12 @@ pub fn struct_partial_eq<S: Struct>(a: &S, b: &dyn Reflect) -> Option<bool> { | |||||||
| /// ```
 | /// ```
 | ||||||
| #[inline] | #[inline] | ||||||
| pub fn struct_debug(dyn_struct: &dyn Struct, f: &mut Formatter<'_>) -> std::fmt::Result { | pub fn struct_debug(dyn_struct: &dyn Struct, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||||
|     let mut debug = f.debug_struct(dyn_struct.reflect_type_path()); |     let mut debug = f.debug_struct( | ||||||
|  |         dyn_struct | ||||||
|  |             .get_represented_type_info() | ||||||
|  |             .map(|s| s.type_path()) | ||||||
|  |             .unwrap_or("_"), | ||||||
|  |     ); | ||||||
|     for field_index in 0..dyn_struct.field_len() { |     for field_index in 0..dyn_struct.field_len() { | ||||||
|         let field = dyn_struct.field_at(field_index).unwrap(); |         let field = dyn_struct.field_at(field_index).unwrap(); | ||||||
|         debug.field( |         debug.field( | ||||||
|  | |||||||
| @ -453,7 +453,12 @@ pub fn tuple_struct_debug( | |||||||
|     dyn_tuple_struct: &dyn TupleStruct, |     dyn_tuple_struct: &dyn TupleStruct, | ||||||
|     f: &mut Formatter<'_>, |     f: &mut Formatter<'_>, | ||||||
| ) -> std::fmt::Result { | ) -> std::fmt::Result { | ||||||
|     let mut debug = f.debug_tuple(dyn_tuple_struct.reflect_type_path()); |     let mut debug = f.debug_tuple( | ||||||
|  |         dyn_tuple_struct | ||||||
|  |             .get_represented_type_info() | ||||||
|  |             .map(|s| s.type_path()) | ||||||
|  |             .unwrap_or("_"), | ||||||
|  |     ); | ||||||
|     for field in dyn_tuple_struct.iter_fields() { |     for field in dyn_tuple_struct.iter_fields() { | ||||||
|         debug.field(&field as &dyn Debug); |         debug.field(&field as &dyn Debug); | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 davier
						davier