Skip to content

Commit

Permalink
Fix debug printing for dynamic types (#10740)
Browse files Browse the repository at this point in the history
# 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 <[email protected]>
  • Loading branch information
Davier and MrGVSV authored Dec 12, 2023
1 parent 9c85769 commit 55402bd
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 3 deletions.
8 changes: 7 additions & 1 deletion crates/bevy_reflect/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use bevy_reflect_derive::impl_type_path;
use std::{
any::{Any, TypeId},
fmt::Debug,
fmt::{Debug, Formatter},
hash::{Hash, Hasher},
};

Expand Down Expand Up @@ -301,6 +301,12 @@ impl Reflect for DynamicArray {
fn is_dynamic(&self) -> bool {
true
}

fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "DynamicArray(")?;
array_debug(self, f)?;
write!(f, ")")
}
}

impl Array for DynamicArray {
Expand Down
67 changes: 67 additions & 0 deletions crates/bevy_reflect/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
mod glam {
use super::*;
Expand Down
7 changes: 6 additions & 1 deletion crates/bevy_reflect/src/struct_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,12 @@ pub fn struct_partial_eq<S: Struct>(a: &S, b: &dyn Reflect) -> Option<bool> {
/// ```
#[inline]
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() {
let field = dyn_struct.field_at(field_index).unwrap();
debug.field(
Expand Down
7 changes: 6 additions & 1 deletion crates/bevy_reflect/src/tuple_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,12 @@ pub fn tuple_struct_debug(
dyn_tuple_struct: &dyn TupleStruct,
f: &mut Formatter<'_>,
) -> 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() {
debug.field(&field as &dyn Debug);
}
Expand Down

0 comments on commit 55402bd

Please sign in to comment.