rune
rune copied to clipboard
Add support for matching over external enums and unit structs
We currently only support matching over external structs, such as:
#[derive(Any)]
struct External {
#[rune(get)]
field: u32,
}
Which would allow for the following in Rune:
pub fn main(external) {
match external {
External { field } => field,
}
}
These are currently not supported, but both could and should be:
Tuple structs
#[derive(Any)]
struct External(#[rune(get)] u32);
In Rune:
pub fn main(external) {
match external {
External(field) => field,
}
}
Enum variants:
#[derive(Any)]
enum External {
First,
Second(#[rune(get)] u32),
Third {
#[rune(get)]
field: u32,
}
}
In Rune:
pub fn main(external) {
match external {
External::First => {},
External::Second(field) => field,
External::Third { field } => field,
}
}
Implementation details
It is necessary to add getters for accessing fields of external types, because Rune has no other way of doing so. It's also a natural extension of how #[rune(get)]
currently works. I.e. it permits external.field
to work as intended.
This requires that field functions are extended to be capable of addressing the "numeric indexes" of tuples. Which is perfectly doable but would require additional APIs to Module
. Similar to how we have Module::field_fn
it might be appropriate to add Module::tuple_fn
.
In order to support enums we also need additional ways to register enum metadata. in #384 we introduced Module::struct_meta
which is used for registering the limited amount of metadata necessary to compile matches over structs. For enums this would have to be much more exhaustive. What we need it to register is:
- A collection of all the variant names.
- For each variant, if they are struct, tuple, or empty.
- For struct variants, the names of its fields.
- For tuple variants, how many items it has. E.g.
Foo(a, b)
has 2 items.