Expand description
Concise macros for extracting bits from integers and combining bits into integers. No scary syntax. Minimal magic.
use splitbits::splitbits;
// Parse the template provided ("aaabbbbb"), apply it to the input, then generate a struct
// populated with the bit field values.
let fields = splitbits!(0b11110000, "aaabbbbb");
// Single-letter field names, generated from the unique letters in the template above.
assert_eq!(fields.a, 0b111);
assert_eq!(fields.b, 0b10000);§Why use splitbits?
Splitbits replaces tedious, error-prone bit operations with a simple template format, making it easy to extract bits into variables.
Every operation than can be executed at compile time is. Generated code should be as efficient as hand-written bit operations.
Splitbits is intended for cases where bitfield is too heavy-weight syntactically: when you don’t want to explicitly declare a new struct for data that you won’t use as a return value or argument.
§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.) By default, each field will be stored in the smallest unsigned integer type possible.combinebits!- Combine bits of multiple integers into a single integer.use splitbits::combinebits; let b: u8 = 0b1010_1010; let m: u8 = 0b1111; let e: u8 = 0b0000; let result = combinebits!("bbbb bbbb mmmm eeee"); assert_eq!(result, 0b1010_1010_1111_0000);splitbits_then_combine!- Extract bit fields from multiple integers then combine them into a single integer.use splitbits::splitbits_then_combine; let output = splitbits_then_combine!( 0b1111_0000, "aaaa ..bb", // input 0, input template 0, 0b1011_1111, "cc.. ....", // input 1, input template 1 "aaaa bbcc", // output template ); assert_eq!(output, 0b1111_0010);replacebits!- Replace some of the bits of an integer with bits from other integers.use splitbits::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!(0b10000001, "aaa..bb."); assert_eq!(result, 0b10100011);
§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 these more specialized 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 theletbinding.splitbits_named_into!- Same assplitbits_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.
§Template syntax
Templates are a string of characters that represent the names and bit-placements of fields within an integer.
Example: "..aa bccc dddd 1010"
The possible elements of a template are:
- Names - a single letter that indicates the name of a field. (Currently only ASCII allowed.)
- Placeholders - a period that indicates a digit that will be ignored.
- Literals - a literal digit of the numeric base of the template (e.g. binary or hexadecimal).
- Whitespaces - an empty space character used to make formatting more human-friendly, paralleling how underscores can be added to integer literals.
The bits of a field are usually contiguous within a template, but they don’t have to be:
"aabbbbaa". This template will interpret a as a single field, with no bits present between
the halves.
§Restrictions
- Templates (currently) must have a standard integer width (8, 16, 32, 64, or 128 bits).
- Placeholders cannot be used in the template for
combinebits!, nor in the output template ofsplitbits_then_combine!. They are not meaningful in those contexts. - Literals (currently) cannot be used in the template for
splitbits!nor the input templates ofsplitbits_then_combine!. In the future, literals could be used in these contexts for input validation.
§Settings
Settings can be passed as the first argument to a macro to change some behaviors from the
default. Their syntax is similar to named arguments in Python: setting_type=setting_value.
There are currently two setting types:
- min - sets the minimum size of variable that can be produced by the
splitbits!family of macros. Must be set if you don’t want booleans generated for 1-bit fields.- For standard (non-ux) macros, the valid setting values are
bool(the default),u8,u16,u32,u64, andu128. See examples atsplitbits!. - For ux macros, the valid setting values are
bool(the default) oruX, where X is between 1 and 128 (both inclusive). See examples atsplitbits_ux!.
- For standard (non-ux) macros, the valid setting values are
- overflow - sets the behavior to use if the value of an input variable is larger than the
corresponding slot in the template. Used in
combinebits!andreplacebits!. Valid setting values aretruncate(the default),panic,corrupt, orsaturate.
Macros§
- combinebits
- Combine bits of multiple variables into a single variable as defined by a template.
- combinehex
- Same as
combinebits!except the template uses hexadecimal digits rather than binary digits. - replacebits
- Replace some of the bits in an integer with bits from other variables, as specified by a template. Placeholders (periods) mark bits that will not be replaced.
- replacehex
- Same as
replacebits!, except the digits in the template are hexadecimal rather than binary. - splitbits
- Extract bit fields from an integer data type by matching against a template, storing them as fields in a generated struct.
- splitbits_
named - Same as
splitbits!, except that full-length variable names can be used. Returns a tuple instead of a generated struct. If there is only a single field specified in the template, returns a single variable instead (not a 1-tuple). Fields are returned in the order that they first appear in the template, and the single character template names are discarded. - splitbits_
named_ into - Same as
splitbits_named!, except the caller can provide the field types, rather than the macro inferring them. The custom types must implement From for the relevant integer types. - splitbits_
named_ into_ ux - Same as
splitbits_named_into!, except that the widths of the generated fields are precise to-the-bit. A dependency on the ux crate is required. - splitbits_
named_ ux - Same as
splitbits_named!, except that the widths of the generated fields are precise to-the-bit. A dependency on the ux crate is required. - splitbits_
then_ combine - Extract bits from multiple input integers by matching against input templates, then combine those bits into to an integer matching the output template.
- splitbits_
ux - Same as
splitbits!, except that the widths of the generated fields are precise to-the-bit. A dependency on the ux crate is required. - splithex
- Same as
splitbits!, except that the template characters represent hexadecimal digits. - splithex_
named - Same as
splitbits_named!except with hexadecimal digits in the template. - splithex_
named_ into - Same as
splithex_named!, except the caller can provide the field types, rather than the macro inferring them. The custom types must implement From/Into for the relevant integer types. - splithex_
named_ into_ ux - Same as
splithex_named_into!, except the widths of the generated fields are precise to-the-bit. - splithex_
named_ ux - Same as
splithex_named!, except that the widths of the generated fields are precise to-the-bit. A dependency on the ux crate is required. - splithex_
then_ combine - Same as
splitbits_then_combine!, except with hexadecimal digits in the template. - splithex_
ux - Same as
splithex!, except that the widths of the generated fields are precise to-the-bit. A dependency on the ux crate is required.