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