Hello! I came up with the idea of such a type of enum:
enum Ethertype {
Ipv6, // = 0x86DD,
Others(u16)
}
This type of enum cannot be marked as #[repr(u16)]
in current Rust version, and we should write From and Into traits to convert between such an enum to u16. Also, this enumeration costs more than one u16
in memory, as number of values would be 2^16 + 1
, it's more than 2^16
as a bare u16 value.
If Rust has a language feature like this:
#[repr(enum_others, u16)]
enum Ethertype {
Ipv6 = 0x86DD,
Others(u16)
}
Then we could use such functions conveniently:
/* packet.ether_type: u16 */
let typ = packet.ether_type as Ethertype;
// or
match packet.ether_type as Ethertype {
Ipv6 => process_ipv6(),
Others(typ) => println!("unsupported type: {}", typ),
}
// both prints '2'
println!("{}", mem::size_of::<Ethertype>());
println!("{}", mem::size_of::<u16>());
// ether_type == Ipv6 => value1 = 0x86DD
// ether_type == Others(other_value) => value1 = other_value
let value1 = ether_type as u16;
// u16_value = 0x86DD => typ = Ethertype::Ipv6
// u16_value = others => typ = Ethertype::Others(u16_value)
let typ = u16_value as Ethertype;
I believe such an enum operation would be useful not only in network packet processing, but also in embedded system developent and other usages.
#[repr(enum_others, usize)]
enum RiscvTrap {
UserSoft = INTERRUPT + 0,
/* ... */
Others(usize)
}
// prints '8' on 64-bit systems
println!("{}", mem::size_of::<RiscvTrap>());
Any further ideas or would this kind of enum be okay for Rust? (Should I write it to a proc macro?)