zerocopy

El crate zerocopy (de Fuchsia) proporciona traits y macros para realizar conversiones seguras entre secuencias de bytes y otros 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]
    );
}

No es adecuado para MMIO (ya que no utiliza lecturas y escrituras volátiles), pero puede ser útil para trabajar con estructuras compartidas con hardware (por ejemplo, mediante DMA) o enviadas a través de alguna interfaz externa.

  • FromBytes se puede implementar en tipos en los que cualquier patrón de bytes es válido, por lo que se puede convertir de forma segura a partir de una secuencia de bytes que no es fiable.
  • Si se intenta derivar FromBytes para estos tipos, se produciría un error, pues RequestType no utiliza todos los valores u32 posibles como discriminantes y, por tanto, todos los patrones de bytes son válidos.
  • zerocopy::byteorder tiene tipos para primitivos numéricos conscientes del orden de bytes.
  • Ejecuta el ejemplo con cargo run en src/bare-metal/useful-crates/zerocopy-example/. (No se ejecutará en el playground debido a la dependencia del crate).