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).