Macro format_struct::format_struct
source · macro_rules! format_struct { ($($(#[$m:meta])* $vis:vis struct $endian:tt $name:ident { $($(#[doc = $field_doc:literal])* $field_vis:vis $field_name:ident: $ty:tt),*, })+) => { ... }; (@impl_conv $name:ident$(<$gen:ident>)? size $size_expr:expr) => { ... }; (@endian_type little) => { ... }; (@endian_type big) => { ... }; (@endian_type dynamic) => { ... }; (@wrapper_type [$ty:ident; $n:literal] $endian:tt) => { ... }; (@wrapper_type u8 $endian:tt) => { ... }; (@wrapper_type i8 $endian:tt) => { ... }; (@wrapper_type u16 $endian:tt) => { ... }; (@wrapper_type i16 $endian:tt) => { ... }; (@wrapper_type u32 $endian:tt) => { ... }; (@wrapper_type i32 $endian:tt) => { ... }; (@wrapper_type u64 $endian:tt) => { ... }; (@wrapper_type i64 $endian:tt) => { ... }; (@wrapper_type u128 $endian:tt) => { ... }; (@wrapper_type i128 $endian:tt) => { ... }; }
Expand description
Defines a structure that can be transmuted from/into a byte slice for parsing/constructing binary formats in a zero-copy way.
The macro achieves this by replacing all multibyte integers with wrapper types that are byte arrays internally and only allowing integer and fixed size array fields in a structure.
Accepted syntax is similar to a standard structure definition in Rust with some differences:
- The
struct
keyword is followed by eitherlittle
orbig
keywords if you want fixed endianness ordynamic
keyword if you want dynamic endianness. - Fields of the generated structure may only have documentation meta, other meta types are disallowed.
§Examples
format_struct! {
/// A little-endian test structure.
#[derive(Default, Clone)]
pub struct little Test {
/// this byte is public
pub byte: u8,
short: u16,
word: i32,
dword: i64,
qword: u128,
byte_arr: [u8; 16],
}
}
It is also possible to define multiple structures in one macro invocation:
format_struct! {
struct little Foo {
byte: u8,
}
struct big Bar {
a: u64,
}
pub struct little Baz {
z: [u8; 33],
}
}
§Allowed field types
Currently only integer types (u8
, u16
, u32
, u64
, u128
and their signed counterparts) are allowed and
statically sized integer arrays ([u8; N]
).
§Layout
The fields in the structure are laid out in declaration order without any padding. That means that the following structure will take 7 bytes instead of 16 you might expect:
format_struct! {
struct little SmallStruct {
byte: u8,
dword: u64,
}
}