splitbits

Macro splitbits_then_combine

source
splitbits_then_combine!() { /* proc-macro */ }
Expand description

Extract bits from multiple input integers by matching against input templates, then combine those bits into to an integer matching the output template.

The width of a field must match between the input templates and output template.

Placeholder periods are usually needed with this macro for ignoring unused input bits.

use splitbits::splitbits_then_combine;

// While its possible to use this macro on a single line, it's easiest to see the structure like
// this:
// let output = splitbits_then_combine!(
//    input0, input_template0,
//    input1, input_template1,
//    ...
//    inputX, input_templateX,
//            output_template,
// );
let output = splitbits_then_combine!(
    0b1111_0000, "aaaa ..bb",
    0b1011_1111, "cc.. ....",
                 "aaaa bbcc",
);
assert_eq!(output, 0b1111_0010);
// Or the equivalent, with actual input variables, as it would occur in real code:
use splitbits::splitbits_then_combine;

let primary = 0b1111_0000;
let supplement = 0b1011_1111;
let output = splitbits_then_combine!(
    primary,    "aaaa ..bb",
    supplement, "cc.. ....",
                "aaaa bbcc",
);
assert_eq!(output, 0b1111_0010);

Literal 1s and 0s can be hard-coded into the output template:

use splitbits::splitbits_then_combine;

let output = splitbits_then_combine!(
    0b1111_0000, "aaaa ..bb",
    0b1011_1111, "cc.. ....",
                 "aaaa 0101 0000 bbcc",
);
assert_eq!(output, 0b1111_0101_0000_0010);

An input field can be split into segments by the output template:

use splitbits::splitbits_then_combine;

let output = splitbits_then_combine!(
    0b1111_0000, "aaaa aa..",
    0b1011_1111, "..bb bbbb",
                 "aaab bbbb b000 1aaa",
);
assert_eq!(output, 0b1111_1111_1000_1100);

Segments of a field can be combined from different input locations into a single output field.

use splitbits::splitbits_then_combine;

let output = splitbits_then_combine!(
    0b1111_0000, "aaaa ..aa",
    0b0011_1010, "..aa bbbb",
                 "aaaa aaaa 0000 bbbb",
);
assert_eq!(output, 0b1111_0011_0000_1010);

Having all these features in one macro means that there are multiple ways to achieve an outcome, so consider which way leads to the best readability on a case-by-case basis.