Bit-level packing and unpacking for Rust
Introduction
Packing and unpacking bit-level structures is usually a programming tasks that needlessly reinvents the wheel. This library provides a meta-programming aproach, using attributes to document fields and how they should be packed. The resulting trait implementations provide safe packing, unpacking and runtime debugging formatters with per-field documentation generated for each structure.
Features
- Plain Rust structures, decorated with attributes
- MSB or LSB integers of user-defined bit widths
- Primitive enum code generation helper
- MSB0 or LSB0 bit positioning
- Documents the field's packing table
- Runtime packing visualization
- Nested packed types
- Arrays of packed structures as fields
- Reserved fields, their bits are always 0 or 1
Sample usage
Cargo.toml
[]
= "0.2"
= "0.2"
Including the library and the code generator
extern crate packed_struct;
extern crate packed_struct_codegen;
#
Example of a single-byte structure, with a 3 bit integer, primitive enum and a bool field.
extern crate packed_struct;
extern crate packed_struct_codegen;
use *;
Packing attributes
Syntax
extern crate packed_struct;
extern crate packed_struct_codegen;
#
Per-structure attributes
Attribute | Values | Comment |
---|---|---|
size_bytes |
1 ... n |
Size of the packed byte stream |
bit_numbering |
msb0 or lsb0 |
Bit numbering for bit positioning of fields. Required if the bits attribute field is used. |
endian |
msb or lsb |
Default integer endianness |
Per-field attributes
Attribute | Values | Comment |
---|---|---|
bits |
0 , 0..1 , ... |
Position of the field in the packed structure. Three modes are supported: a single bit, the starting bit, or a range of bits. See details below. |
bytes |
0 , 0..1 , ... |
Same as above, multiplied by 8. |
size_bits |
1 , ... |
Specifies the size of the packed structure. Mandatory for certain types. Specifying a range of bits like bits="0..2" can substite the required usage of size_bits . |
size_bytes |
1 , ... |
Same as above, multiplied by 8. |
element_size_bits |
1 , ... |
For packed arrays, specifies the size of a single element of the array. Explicitly stating the size of the entire array can substite the usage of this attribute. |
element_size_bytes |
1 , ... |
Same as above, multiplied by 8. |
ty |
enum |
Packing helper for primitive enums. |
endian |
msb or lsb |
Integer endianness. Applies to u16/i16 and larger types. |
Bit and byte positioning
Used for either bits
or bytes
on fields. The examples are for MSB0 positioning.
Value | Comment |
---|---|
0 |
A single bit or byte |
0.. , 0: |
The field starts at bit zero |
0..2 |
Exclusive range, bits zero and one |
0:1 , 0..=1 |
Inclusive range, bits zero and one |
More examples
Mixed endian integers
extern crate packed_struct;
extern crate packed_struct_codegen;
use *;
24 bit LSB integers
extern crate packed_struct;
extern crate packed_struct_codegen;
use *;
Nested packed types within arrays
extern crate packed_struct;
extern crate packed_struct_codegen;
use *;
Primitive enums with simple discriminants
Supported backing integer types: u8
, u16
, u32
, u64
, i8
, i16
, i32
, i64
.
Explicit or implicit backing type:
extern crate packed_struct;
extern crate packed_struct_codegen;
#