Skip to content

Commit ab314e3

Browse files
committed
allow unnamed variables in match class + tests
1 parent bf3f1d5 commit ab314e3

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

godot-core/src/classes/match_class.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
/// # // Hack to keep amount of SELECTED_CLASSES limited:
2727
/// # type InputEventMouseButton = InputEventAction;
2828
/// # type InputEventMouseMotion = InputEventAction;
29+
/// # type InputEventKey = InputEventAction;
2930
/// // Basic syntax.
3031
/// let event: Gd<InputEvent> = some_input();
3132
///
3233
/// let simple_dispatch: i32 = match_class! { event,
3334
/// button @ InputEventMouseButton => 1,
3435
/// motion @ InputEventMouseMotion => 2,
3536
/// action @ InputEventAction => 3,
37+
/// key @ InputEventKey => 4,
3638
/// _ => 0, // Fallback.
3739
/// };
3840
///
@@ -50,14 +52,18 @@
5052
/// // Qualified types supported:
5153
/// action @ godot::classes::InputEventAction => 3,
5254
///
55+
/// // If you're only interested in the class and not the object,
56+
/// // discard it with either `_` or `_variable`:
57+
/// _ @ InputEventKey => 4,
58+
///
5359
/// // Fallback with variable -- retrieves original Gd<InputEvent>.
5460
/// original => 0,
5561
/// // Can also be used with mut:
5662
/// // mut original => 0,
5763
/// // If the match arms have type (), we can also omit the fallback branch.
5864
/// };
5965
///
60-
/// // event_type is now 0, 1, 2, or 3
66+
/// // event_type is now 0, 1, 2, 3 or 4
6167
/// ```
6268
///
6369
/// # Expression and control flow
@@ -99,6 +105,16 @@ macro_rules! match_class_muncher {
99105
}
100106
}};
101107

108+
// _ @ Class => { ... }.
109+
($subject:ident, _ @ $Ty:ty => $block:expr, $($rest:tt)*) => {{
110+
match $subject.try_cast::<$Ty>() {
111+
Ok(_) => $block,
112+
Err(__obj) => {
113+
$crate::match_class_muncher!(__obj, $($rest)*)
114+
}
115+
}
116+
}};
117+
102118
// mut variable => { ... }.
103119
($subject:ident, mut $var:ident => $block:expr $(,)?) => {{
104120
let mut $var = $subject;

itest/rust/src/engine_tests/match_class_test.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,29 @@ fn match_class_basic_mut_dispatch() {
5959
to_free.free();
6060
}
6161

62+
#[itest]
63+
fn match_class_basic_unnamed_dispatch() {
64+
let node3d = Node3D::new_alloc();
65+
let obj: Gd<Object> = node3d.upcast();
66+
let to_free = obj.clone();
67+
68+
let result = match_class! { obj,
69+
node @ Node2D => {
70+
require_node2d(&node);
71+
1
72+
},
73+
_ @ Node3D => 2,
74+
node @ Node => {
75+
require_node(&node);
76+
3
77+
},
78+
_ => 4 // No comma.
79+
};
80+
81+
assert_eq!(result, 2);
82+
to_free.free();
83+
}
84+
6285
#[itest]
6386
fn match_class_shadowed_by_more_general() {
6487
let node2d = Node2D::new_alloc();
@@ -172,13 +195,16 @@ fn match_class_unit_type() {
172195
let mut val = 0;
173196

174197
match_class! { obj,
198+
_ @ Node3D => {
199+
val = 1;
200+
},
175201
mut node @ Node2D => {
176202
require_mut_node2d(&mut node);
177-
val = 1;
203+
val = 2;
178204
},
179205
node @ Node => {
180206
require_node(&node);
181-
val = 2;
207+
val = 3;
182208
},
183209
// No need for _ branch since all branches return ().
184210
}

0 commit comments

Comments
 (0)