I have an enum which represents every possible instruction on an 8080 processor. An instruction can be 1, 2 or 3 bytes long, depending on whether it has information associated with it and how much. For example:
#[allow(non_camel_case_types)]
enum Instruction {
None,
NOP,
LXI_B_D16(u8, u8),
STAX_B,
INX_B,
MVI_B_D8(u8),
MVI_C_D8(u8),
RRC,
LXI_D_D16(u8, u8),
MVI_D_D8(u8),
RAL,
DCR_E,
MVI_E_D8(u8),
LXI_H_D16(u8, u8),
SHLD(u16),
LHLD(u16),
// ...
}
When it comes to assigning memory addresses to instructions, I iterate instruction-by-instruction through the binary file, using the length of each instruction to make sure my loop doesn't land halfway through an instruction and give me garbage. I do this with a huge match expression, which returns a tuple containing the correct instruction and its length:
match value {
0x00 => (Instruction::NOP, 1),
0x01 => (Instruction::LXI_B_D16(d1, d2), 3),
0x02 => (Instruction::STAX_B, 1),
0x05 => (Instruction::DCR_B, 1),
0x06 => (Instruction::MVI_B_D8(d1), 2),
0x07 => (Instruction::RLC, 1),
0x0e => (Instruction::MVI_C_D8(d1), 2),
0x0f => (Instruction::RRC, 1),
0x11 => (Instruction::LXI_D_D16(d1, d2), 3),
0x19 => (Instruction::DAD_D, 1),
// ...
}
This is ugly, but I don't want to associate this length number into the type because it's really only important when I'm parsing the file.
It seems like I should be able to just infer the length of an instruction from the shape of the variant. Anything with no argument is length 1, anything with one u8 argument is length 2, and anything with one u16 or two u8 arguments is length 3.
I haven't been able to work out how to get this shape programatically. I can't call len()
on it like an array or vector, for example.
I don't think this is a duplicate of How to get the number of elements in an enum as a constant value? as I'm not looking for a way to get the number of variants in the enum, but the number of arguments of any individual variant.