Zerocopy 0.8.37: Dynamically Sized Transmutes
We're excited to announce zerocopy 0.8.37, the latest release of our toolkit for safe, low-level memory manipulation and casting. This release generalizes our transmute_ref! and transmute_mut! macros to handle not only transmutations between sized types (playground):
let src: &[u16; 6] = &[0, 1, 2, 3, 4, 5];
let dst: &[u8; 12] = transmute_ref!(src);
...but now also unsized-to-unsized transmutations (playground):
let src: &[u16] = &[0, 1, 2, 3, 4, 5][..];
let dst: &[u8] = transmute_ref!(src);
...and even sized-to-unsized transmutations (playground):
use zerocopy::*;
#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C, align(2))]
struct PacketHeader {
src_port: [u8; 2],
dst_port: [u8; 2],
length: [u8; 2],
checksum: [u8; 2],
}
#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
header: PacketHeader,
body: [u8],
}
// A sized source:
let src: [u16; 6] = [0, 1, 2, 3, 4, 5];
// An unsized destination:
let dst: &Packet = transmute_ref!(&src);
Unlike our conversion methods (e.g., FromBytes::ref_from_bytes), our transmute macros are capable of statically checking (i.e., at no runtime cost) that the size and address of the transmutation source satisfies the alignment requirements of the destination type.
We've also extended support for these complex transmutations to our try_transmute_ref! and try_transmute_mut! macros, enabling their use in fallible conversions.