strum
strum copied to clipboard
EnumProperty: opting-in stronger guarantees on properties
Currently deriving EnumProperty
results in a bunch of get*() -> Option<*>
. This works quite well in general, but it moves some property checking to runtime option-handling.
What I'd like to see provided in this crate is some way of opting-in to stronger guarantees and typing of properties, such that I could:
- annotate the enum to require that all variants declare some specific property
- either annotate or infer the type of this mandatory property
- generate specific getter for each mandatory property, such that there is a single
get_prop() -> PropType
generated
The usestory for this is: complex enums declarations (with attributes) can become quite long and some variants can end up with missing prop-attributes or with copy-paste type mistakes. Those would only be catched when unwrapping the Option at runtime, but the compiler should be able to sanity-check this at buildtime. Also it would make the getter more specifically named and remove the needs of Option wrapping.
Some hypotetical syntax (but feel free to design your one discarding this) could be:
#[derive(EnumProperty)]
#[strum(props(room: i32))]
enum Class {
#[strum(props(teacher="foo", room=101))]
History,
#[strum(props(room=2))]
Mathematics,
#[strum(props(room=-1))]
Science,
}
fn main() {
let history = Class::History;
assert_eq!(101, history.get_room());
}
Where adding a variant without the room
prop or with a non-matching type would fail type-checking / compilation.
This is a good idea!
Originally when I wrote the EnumProperty
code, custom attributes were relatively limited in that they supported types other than strings, but it required a feature gate to use other types. I'm not sure if that's changed, but that doesn't mean I can't add it now and wait for it to be stabilized.
A quick note though, I don't believe -1
is supported though since that's an expression, not a literal in the grammar sense.
With respect to custom getters, I'm debating whether or not it makes sense to derive a trait YourStructPropertyGetters
with your specific methods and implementing that. With these auto-derives, I'm always hesitant to implement them directly on the type because it can cause collisions with other user defined methods.
A quick note though, I don't believe -1 is supported though since that's an expression, not a literal in the grammar sense.
I fear you are right: https://github.com/rust-lang/rust/issues/34981#issuecomment-277510573
With these auto-derives, I'm always hesitant to implement them directly on the type because it can cause collisions with other user defined methods.
In this case, the user is almost explicitly naming the method, so it should be OK.