Skip to content

Commit 0557617

Browse files
committed
All engine enums have now custom Debug implementation
Changes the Debug representation from: SomeEnum { ord: 43 } to: CONSTANT If there are multiple matching constants with the same value, the first one is displayed.
1 parent acfa785 commit 0557617

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

godot-codegen/src/generator/enums.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ pub fn make_enum_definition_with(
5050
let engine_trait = enum_.engine_trait();
5151

5252
let definition = define_enum.then(|| {
53+
let debug_impl = make_enum_debug_impl(enum_);
54+
5355
// Workaround because traits are defined in separate crate, but need access to field `ord`.
5456
let vis = (!define_traits).then(|| {
5557
quote! {
@@ -68,6 +70,8 @@ pub fn make_enum_definition_with(
6870
impl #name {
6971
#( #enumerators )*
7072
}
73+
74+
#debug_impl
7175
}
7276
});
7377

@@ -121,6 +125,41 @@ fn make_enum_index_impl(enum_: &Enum) -> Option<TokenStream> {
121125
})
122126
}
123127

128+
/// Implement `Debug` trait for the enum.
129+
fn make_enum_debug_impl(enum_: &Enum) -> TokenStream {
130+
let enum_name = &enum_.name;
131+
let enum_name_str = enum_name.to_string();
132+
133+
let enumerators = enum_.enumerators.iter().map(|enumerator| {
134+
let Enumerator { name, .. } = enumerator;
135+
let name_str = name.to_string();
136+
quote! {
137+
Self::#name => #name_str,
138+
}
139+
});
140+
141+
quote! {
142+
impl std::fmt::Debug for #enum_name {
143+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144+
// Many enums have duplicates, thus allow unreachable.
145+
// In the future, we could print sth like "ONE|TWO" instead (at least for unstable Debug).
146+
#[allow(unreachable_patterns)]
147+
let enumerator = match *self {
148+
#( #enumerators )*
149+
_ => {
150+
f.debug_struct(#enum_name_str)
151+
.field("ord", &self.ord)
152+
.finish()?;
153+
return Ok(());
154+
}
155+
};
156+
157+
f.write_str(enumerator)
158+
}
159+
}
160+
}
161+
}
162+
124163
/// Creates an implementation of the engine trait for the given enum.
125164
///
126165
/// This will implement the trait returned by [`Enum::engine_trait`].

godot-codegen/src/models/domain/enums.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ pub struct Enum {
2424
impl Enum {
2525
/// Which traits should be derived for this enum.
2626
pub fn derives(&self) -> Vec<Ident> {
27-
let mut derives = vec!["Copy", "Clone", "Eq", "PartialEq", "Hash", "Debug"];
27+
// Debug is implemented manually, using enumerator name. This can be derived once we use proper enums.
28+
let mut derives = vec!["Copy", "Clone", "Eq", "PartialEq", "Hash"];
2829

2930
if self.is_bitfield {
3031
derives.push("Default");

itest/rust/src/object_tests/dynamic_call_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ fn dynamic_call_parameter_mismatch() {
135135
"godot-rust function call failed: Object::call(&\"take_1_int\", [va] \"string\")\
136136
\n Source: ObjPayload::take_1_int()\
137137
\n Reason: parameter #0 (i64) conversion\
138-
\n Source: expected type Int, got String: \"string\""
138+
\n Source: expected type INT, got STRING: \"string\""
139139
);
140140

141141
obj.free();
@@ -256,7 +256,7 @@ fn dynamic_call_parameter_mismatch_engine() {
256256
assert_eq!(
257257
call_error.to_string(),
258258
"godot-rust function call failed: Object::call(&\"set_name\", [va] 123)\
259-
\n Reason: parameter #1 conversion -- expected type String, got Int"
259+
\n Reason: parameter #1 conversion -- expected type STRING, got INT"
260260
);
261261

262262
node.free();

0 commit comments

Comments
 (0)