In Rust it is possible to directly convert a byte slice into a struct
. This can be done with the transmute_copy
function—type arguments are required.
By using try_into
and unwrap
, we can convert a range of bytes into the required argument. The transmute_copy
function is unsafe, and the resulting struct
may be invalid.
To begin, we have a Node struct
that has two 32-bit unsigned integers in it. Each Node is 8 bytes. We have the "packed" repr to ensure the data has a consistent layout in memory.
main()
we have a source vector with 16 bytes—this could be read in from a file.transmute_copy()
twice on the source data. The offset local indicates where we start reading the bytes.transmute_copy
. This is fast as it references existing data.use std::mem; #[repr(packed)] #[derive(Debug)] struct Node { id: u32, data: u32, } fn main() { // The input data containing the 2 structs in byte form. let source = vec![0, 2, 10, 4, 200, 100, 2, 4, 0, 40, 10, 2, 1, 50, 20, 7]; // Use transmute_copy to convert the raw bytes into structs. unsafe { // First struct. let offset = 0; let node1 = mem::transmute_copy::<[u8; 8], Node>(&source[offset..offset+8].try_into().unwrap()); // Second struct (offset is 8). let offset = 8; let node2 = mem::transmute_copy::<[u8; 8], Node>(&source[offset..offset+8].try_into().unwrap()); // Print the structs. println!("{:?}", node1); println!("{:?}", node2); } }Node { id: 67764736, data: 67265736 } Node { id: 34220032, data: 118764033 }
The transmute_copy
function does not ensure the resulting struct
will be valid. But if you have complete control over the data source, the program will work correctly.
from_ne_bytes()
to read in the data would avoid the need for unsafe code. It would likely be slower.With transmute_copy
, we can convert bytes to a struct
in an extremely fast and direct way. But this conversion is unsafe—the compiler cannot prove it is correct.