zerocopy

Крейт zerocopy (від Fuchsia) надає трейти та макроси для безпечного перетворення між послідовностями байтів та іншими типами.

use zerocopy::{Immutable, IntoBytes};

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

#[repr(C)]
#[derive(Debug, Default, Immutable, IntoBytes)]
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]
    );
}

Це не підходить для MMIO (оскільки він не використовує непостійні читання та записи), але може бути корисним для роботи зі структурами, спільними з обладнанням, наприклад, з прямим доступом до пам'яті (DMA), або переданими через зовнішній інтерфейс.

  • FromBytes можна реалізувати для типів, для яких дійсний будь-який шаблон байтів, і тому його можна безпечно перетворити з ненадійної послідовності байтів.
  • Спроба отримати FromBytes для цих типів не вдасться, оскільки RequestType не використовує всі можливі значення u32 як дискримінанти, тому не всі шаблони байтів є дійсними.
  • zerocopy::byteorder має типи для числових примітивів з урахуванням порядку байтів.
  • Запустіть приклад із cargo run у src/bare-metal/useful-crates/zerocopy-example/. (Він не працюватиме на Rust Playground через залежність від крейту.)