I want to iterate over all values of an enum, some values hold data types, others do not.
I did some reading and the strum crate was mentioned. Is there another way to do this?
Ideally this will not need to be changed if more enums are added.
Thanks!
Why do you need to iterate over the values of an enum? Maybe if you could show a real case someone would be able to suggest the best way to do what you want, even if proper enumerating all values is not supported by Rust.
I am building a simple bytecode interpreter to learn Rust and want to write test cases where I test different sequences of instructions. One test case I disassemble the byte code hence using every enum is needed for setup.
For enums with unit variants, you could write a helper function to generate i.e. a Vec for you:
pub enum MyEnum {
First,
Second
}
impl MyEnum {
pub fn get_values() -> Vec<Self> {
let mut values = vec![];
let added_first = values.push(Self::First);
let added_second = values.push(Self::Second);
// A helper check for exhaustiveness to remind us everytime we add a new value
let _exhaustiveness_check = values.iter().all(|value| {
match value {
Self::First => {
let _ = added_first;
true
}
Self::Second => {
let _ = added_second;
true
}
}
});
values
}
}
But if you need to do this for more than one enum, then Strum is the way to go.
So, you want to automatically generate an "array" that contains all possible enum values and then run some test on it, correct? If that is the case I don't see an easy way to do it, because you have some variants with data and even if it would be possible to loop over them you'd still need to decide which data put in them.
I suggest to rework your tests. For a very similar project I wanted to do some fuzzying and in the end I wrote a function that given a (random in my tests) value, generated one of the possible variants: sure you risk to "forget" about a new variant when you add it later but the technique shown by @firebits.io helps.
This is one test case testing if all instructions are written correctly. But of course there are many other test cases that require special sequences of instructions written.
So your function took a random value as argument and generated one of its enum variants that held that value? This seems too imprecise for testing if source code is compiled correctly.
Do you think there is away around thinking of the instruction sequence that e.g. a function call needs to be compiled to and writing these by hand for a test case?
I have a question: There is only one testcase where I test whether all the enum variants of OpCode are used as byte code instructions. Setting this up seems like it would require one large function. But apart from that every other test case seems like it requires specific byte code instructions.
It will be a lot of effort just to write all these tests and it will be hard to structure this coherently.
Do you have another idea of what I could try?
Is there a way to do this using the static keyword? That way I would need to write less code omitting the checking if all variants are enumerated. Also, when I expand the enumeration I already alter the function so I should remember to add more values to Vec. So it seems superfluous.
sorry I was busy doing something else. I thought I could use static like this, with all enum variants.
However I did not check whether it would compile before writing this...