zerocopy

O crate zerocopy (do Fuchsia) fornece traits e macros para converter com segurança entre sequências de bytes e outros tipos.

use zerocopy::AsBytes;

#[repr(u32)]
#[derive(AsBytes, Debug, Default)]
enum RequestType {
    #[default]
    In = 0,
    Out = 1,
    Flush = 4,
}

#[repr(C)]
#[derive(AsBytes, Debug, Default)]
struct VirtioBlockRequest {
    request_type: RequestType,
    reserved: u32,
    sector: u64,
}

fn main() {
    let request = VirtioBlockRequest {
        request_type: RequestType::Flush,
        sector: 42,
        ..Default::default()
    };

    assert_eq!(
        request.as_bytes(),
        &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]
    );
}

Isso não é adequado para MMIO (pois não usa leituras e gravações voláteis), mas pode ser útil para trabalhar com estruturas compartilhadas com hardware, por exemplo, por DMA, ou enviadas por alguma interface externa.

  • FromBytes pode ser implementado para tipos para os quais qualquer padrão de byte é válido e, portanto, pode ser convertido com segurança de uma sequência de bytes não confiável.
  • Tentar derivar FromBytes para esses tipos falharia, porque RequestType não usa todos os valores u32 possíveis como discriminantes, portanto, nem todos os padrões de bytes são válidos.
  • zerocopy::byteorder tem tipos para primitivas numéricas que levam em consideração a ordem dos bytes.
  • Execute o exemplo com cargo run em src/bare-metal/useful-crates/zerocopy-example/. (Não executará no Playground por causa da dependência do crate).