Typecasts

RecipeCratesCategories
bytemuckbytemuckcat-encoding
zerocopyzerocopycat-encoding

bytemuck

bytemuck bytemuck-crates.io bytemuck-github bytemuck-lib.rs cat-encoding cat-no-std cat-encoding

// use bytemuck::Zeroable;
// use bytemuck::AnyBitPattern;
use bytemuck::NoUninit;

// The bytemuck crate provides functions for reinterpreting one type as another
// without use of `unsafe`, whenever this is safe because both types are “just
// bytes” (no invalid values and no padding).

//#[derive(AnyBitPattern)]

#[repr(C)]
#[derive(Debug, Clone, Copy, NoUninit)]
struct MyStruct {
    x: i32,
    y: [u8; 4],
}

fn to_from_bytes() {
    // Create an instance of MyStruct
    let my_struct = MyStruct {
        x: 42,
        y: [1, 2, 3, 4],
    };
    // MyStruct { x: 42, y: [1, 2, 3, 4] }
    println!("{:?}", my_struct);

    // Convert `MyStruct` to bytes
    // `bytes_of` re-interprets &T as &[u8], but only if T is `NoUninit` that is
    // "plain old data" types with no uninit (or padding) bytes
    let bytes: &[u8] = bytemuck::bytes_of(&my_struct);
    // Bytes: [42, 0, 0, 0, 1, 2, 3, 4] (on a little-endian machine)
    println!("Bytes: {:?}", bytes);

    // FIXME
    // Convert bytes back to `MyStruct`
    // Re-interprets &[u8] as &T, but only if T is `AnyBitPattern`, i.e. "plain
    // old data" types that are valid for any bit pattern. let recovered:
    // &MyStruct = bytemuck::from_bytes(bytes); println!("{:?}", recovered);
}

fn cast() {
    let sixteens: [u16; 4] = [1, 2, 3, 4];
    println!("Sixteens: {:?}", sixteens);
    // `cast` is purely changing the type, thus have no run-time cost.
    // It does not reorder bytes to a specific endianness
    let eights: [u8; 2 * 4] = bytemuck::cast(sixteens);
    println!("Eights: {:?}", eights);
}

fn main() {
    to_from_bytes();
    cast();
}

zerocopy

zerocopy zerocopy-crates.io zerocopy-github zerocopy-lib.rs cat-encoding cat-parsing cat-rust-patterns cat-embedded cat-no-std::no-alloc cat-encoding

zerocopy makes zero-cost memory manipulation safe. It provides a set of traits and utilities to work with types that can be safely interpreted as byte slices.

  • No data copying: Zero-copy avoids unnecessary data copying by directly interpreting the memory of one data structure as another.
  • Performance: Eliminating data copying can significantly improve performance, especially in scenarios involving frequent data transfers between different memory regions (e.g., network I/O, inter-process communication).
  • Safety: The zerocopy crate provides mechanisms to ensure safe and correct zero-copy operations.

Zero-copy is often used in network programming, where high performance and low memory overhead are critical.