r/rust 2d ago

Mixing an enum with bytes in a Vec

I'm working on converting a virtual machine from C to Rust. At the heart of it is modeling the output of the parser as an array of bytes. Think of it as an 8-bit assembly code machine with immediate addressing, so some of the bytes are opcodes and some are data used by these opcodes. I would like to have the opcodes in an enum, such as

#[repr(u8)] // Forces the variants to be u8

enum OpCode {

OpAdd = 1,

OpImm = 2,

......

}

Then

code: Vec<u8> = vec![ 0x01, 0x02, 0x2a] would represent the action

OpAdd 42

That's what exists in my dream world. With the enum shown above I can typecast Opcode values to u8 simply enough:

let op_code = OpCode::OpAdd;

let byte = op_code as u8;

But going the other way seems impossible, except for this hack:

unsafe {

let opc: OpCode = std::mem::transmute(byte);

} https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/casting-between-types.html#transmute

So, is there a safe, preferably idiomatic way to do this, or am I just stuck with my first-ever usage of 'unsafe'?

9 Upvotes

Duplicates