Transmuting u8 buffer to struct in Rust

You can use methods on raw pointers and functions in std::ptr to directly read/write objects in place.

  • std::ptr::read
  • std::ptr::read_unaligned
  • std::ptr::write
  • std::ptr::write_unaligned

In your case:

fn main() {
    let v: Vec<u8> = vec![1, 2, 3];
    let s: MyStruct = unsafe { std::ptr::read(v.as_ptr() as *const _) };
    println!("here is the struct: {:?}", s);
}

I would encourage you to wrap this in a reusable method and perform a length check on the source buffer before attempting the read.


If you don't want to copy the data to the struct but instead leave it in place, you can use slice::align_to. This creates a &MyStruct instead:

#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
struct MyStruct {
    foo: u16,
    bar: u8,
}

fn main() {
    let v = vec![1u8, 2, 3];

    // I copied this code from Stack Overflow
    // without understanding why this case is safe.
    let (head, body, _tail) = unsafe { v.align_to::<MyStruct>() };
    assert!(head.is_empty(), "Data was not aligned");
    let my_struct = &body[0];

    println!("{:?}", my_struct);
}

Here, it's safe to use align_to to transmute some bytes to MyStruct because we've used repr(C, packed) and all of the types in MyStruct can be any arbitrary bytes.

See also:

  • How to read a struct from a file in Rust?
  • Can I take a byte array and deserialize it into a struct?