Concise bit field extraction
Concise macros for extracting bits from integers and combining bits into integers. No scary syntax. Minimal magic.
use splitbits;
// Parse the template provided ("aaabbbbb"), apply it to the input, then generate a struct
// populated with the bit field values.
let fields = splitbits!;
// Single-letter field names, generated from the unique letters in the template above.
assert_eq!;
assert_eq!;
Why use splitbits?
Splitbits allows you to skip tedious, error-prone bit operations, instead providing a simple, terse, and readable template format for specifying which bits correspond to which fields.
Splitbits is intended for cases where bitfield is too heavy-weight: when you don't want to explicitly declare a new struct for data that you won't use as a return value or argument. Splitbits also provides some features that are arguably out of scope for bitfield.
The four base macros
For additional examples, see each macro's page.
- [
splitbits!
] - Extract bit fields out of an integer, storing them as fields of a struct. (See example above.) - [
combinebits!
] - Combine bits of multiple integers into a single integer.use combinebits; let b: u8 = 0b1010_1010; let m: u8 = 0b1111; let e: u8 = 0b0000; let result = combinebits!; assert_eq!;
- [
splitbits_then_combine!
] - Extract bit fields from multiple integers then combine them into a single integer.use splitbits_then_combine; let output = splitbits_then_combine!; assert_eq!;
- [
replacebits!
] - Replace some of the bits of an integer with bits from other integers.use replacebits; let a: u16 = 0b101; let b: u8 = 0b01; // Placeholder periods in the template are the bits that will not be replaced. let result = replacebits!; assert_eq!;
Macro variants
The four base macros cover all the basic functionality that this crate offers and should be sufficient for most use-cases. However, in many situations better ergonomics can be achieved by using the macro variants.
Hexadecimal
All four base macros have equivalents that use hexadecimal digits for their templates rather
than bits (binary digits). The variants are [splithex!
], [combinehex!
],
[splithex_then_combine!
], and [replacehex!
].
Splitbits variants
[splitbits!
] itself has many variants which are intended for better ergonomics for the generated
variables. The basic variants are:
- [
splitbits_named!
] - Used when single-letter variable names aren't descriptive enough. This variant returns a tuple (instead of a struct) of the resulting fields, allowing the caller to assign individual long field names in thelet
binding. - [
splitbits_named_into!
] - Same as [splitbits_named!
] except that the caller specifies the types of the resulting fields, not just their names.into()
is called on each tuple field before it reaches the caller. This is useful for when the default type (the smallest integer type that will fit the field) is a smaller type than the caller would like to use, or if the caller has a newtype that they would like to use instead. - [
splitbits_ux!
] - Used when exact-width integers (e.g. u4, u7, u20) are needed, instead of just the standard types (u8, u16, u32, u64, u128, and bool). Requires the ux crate.
Documentation
Find thorough documentation of this crate and its many macro variants here.
Milestones for future versions
User-facing
- Support template bases beyond binary and hexadecimal (base 8, 32, and 64).
- Add setting for validating splitbits inputs by specifying literals in the template.
- Add file-level config for setting defaults for the overflow and min settings.
- Will allow macro invocations to be more concise at the call-site when the default settings are not desired for a project.
- Allow non-standard template lengths
Code quality
- Represent output as a syntax tree before final code generation.
- Will enable cleaner generated code.
- Will enable better optimization for generated code.
- Will make adding new features easier.
- Will improve code clarity and decrease bugginess by disentangling separate concerns.
- Will fix bug where combinebits input types must not be larger than the template type.
- Extract argument parsing from business logic.
- Will improve code clarity and error handling.