transmute-tools

Proc macros to assist with safely creating transmutable data structures. To be clear, this does not make it safe to use transmute. This is just a collection of tools that might help you do that. The specific, initial use case was to help faithfully reproduce structures from the NVMe spec.

Usage

Location Assertions

transmute_tools::test_structure provides an attribute which allows specifying the location within a struct that a field must be placed:

``` rust use structuralassert::teststructure;

[test_structure(size = 20)]

[repr(C, packed)]

pub struct Foo { #[loc(0:0)] pub a: u8, #[loc(1:1)] pub b: u8, #[loc(2:3)] pub c: u16, #[loc(4:19)] pub d: u128, } ```

Endianness

transmute_tools::endianness provides an attribute which allows specifying specific endianness for a struct's fields. A struct like this:

``` rust

[macro_use]

extern crate transmute_tools;

[endianness(be)]

[repr(C, packed)]

pub struct Foo { pub a: u8, pub b: u8, pub c: u16, #[le] pub d: u128, pub e: Box<()>, } ```

Will generate this:

``` rust

[repr(C, packed)]

pub struct Convert { // Note the missing visbilities. a: u8, b: u8, c: u16, d: u128, pub e: Box<()>, } impl Convert { #[inline] pub fn a(&self) -> u8 { u8::frombe(self.a) } #[inline] pub fn seta(&mut self, value: u8) { self.a = value.tobe(); } #[inline] pub fn b(&self) -> u8 { u8::frombe(self.b) } #[inline] pub fn setb(&mut self, value: u8) { self.b = value.tobe(); } #[inline] pub fn c(&self) -> u16 { u16::frombe(self.c) } #[inline] pub fn setc(&mut self, value: u16) { self.c = value.tobe(); } #[inline] pub fn d(&self) -> u128 { u128::fromle(self.d) } #[inline] pub fn setd(&mut self, value: u128) { self.d = value.tole(); } } ```

NOTE: This must generate functions rather than use something like simple_endianness because access to fields of packed structs when done by value rather than reference.