zerocopy

این crate zerocopy (از Fuchsia) صفات و ماکروهایی را برای تبدیل ایمن بین دنباله‌های بایت و انواع دیگر فراهم می‌کند.

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]
    );
}

این برای MMIO مناسب نیست (زیرا از خواندن و نوشتن فرار یا volatile استفاده نمی‌کند)، اما می‌تواند برای کار با ساختارهای مشترک با سخت افزار مفید باشد. توسط DMA، یا از طریق برخی از رابط‌های خارجی ارسال می‌شود.

  • FromBytes را می‌توان برای انواعی که هر الگوی بایتی برای آنها معتبر است پیاده‌سازی کرد و بنابراین می‌توان با خیال راحت از یک دنباله بایت‌های نامعتبر تبدیل کرد.
  • تلاش برای استخراج FromBytes برای این تایپ‌ها ناموفق خواهد بود، زیرا RequestType از همه مقادیر ممکن u32 به عنوان متمایزکننده استفاده نمی‌کند، بنابراین همه الگوهای بایت معتبر نیستند.
  • zerocopy::byteorder دارای تایپ‌های برای اعداد اولیه مطلع از byte-order است.
  • مثال را با cargo run در src/bare-metal/useful-crates/zerocopy-example/اجرا کنید. (به دلیل وابستگی به crate در Playground اجرا نمی‌شود.)