function bitStruct
bitStruct<T extends BitSchema>(schema: T): Coder<BitStructDecoded<T>>

Creates a Coder for bit-packed structures with MSB-first ordering.

This function creates a coder for structures where fields are packed at the bit level, allowing for efficient binary representations of small values. Fields are encoded in declaration order with MSB-first bit ordering.

Constraints

  • Each field must specify bit count between 1-32
  • Total bits across all fields must be a multiple of 8
  • Values are treated as unsigned integers
  • MSB-first bit ordering (bit 7 is written/read first)

Ref Integration

  • Refs work on the entire bitStruct result, not individual fields
  • Use ref(bitStructCoder) to reference the decoded object

Performance

This coder is optimized for small, bit-aligned structures common in network protocols and binary file formats.

Examples

Simple flags with padding

import { assertEquals } from "@std/assert";
import { bitStruct } from "@hertzg/binstruct/bits";

// 8-bit flags structure
const flags = bitStruct({
  ready: 1,
  error: 1,
  mode: 2,
  _reserved: 4,  // Padding to reach 8 bits
});

const buffer = new Uint8Array(1);
const bytesWritten = flags.encode(
  { ready: 1, error: 0, mode: 3, _reserved: 0 },
  buffer
);

assertEquals(buffer[0], 0b1_0_11_0000);
assertEquals(bytesWritten, 1);

const [decoded, bytesRead] = flags.decode(buffer);
assertEquals(decoded.ready, 1);
assertEquals(decoded.mode, 3);
assertEquals(bytesRead, 1);

Multi-byte network protocol header

import { assertEquals } from "@std/assert";
import { bitStruct } from "@hertzg/binstruct/bits";

// 32-bit protocol header
const header = bitStruct({
  version: 4,      // 4 bits
  type: 4,         // 4 bits
  flags: 8,        // 8 bits
  length: 16,      // 16 bits
});                // Total: 32 bits = 4 bytes

const buffer = new Uint8Array(4);
const data = { version: 1, type: 2, flags: 0xFF, length: 1024 };

header.encode(data, buffer);
const [decoded, bytesRead] = header.decode(buffer);

assertEquals(decoded, data);
assertEquals(bytesRead, 4);

With struct composition

import { assertEquals } from "@std/assert";
import { bitStruct } from "@hertzg/binstruct/bits";
import { struct } from "@hertzg/binstruct/struct";
import { u32le } from "@hertzg/binstruct/numeric";

const flags = bitStruct({
  compressed: 1,
  encrypted: 1,
  version: 6,
});

const packet = struct({
  flags: flags,
  payloadSize: u32le(),
});

const buffer = new Uint8Array(5);
const data = {
  flags: { compressed: 1, encrypted: 0, version: 2 },
  payloadSize: 1024,
};

packet.encode(data, buffer);
const [decoded] = packet.decode(buffer);

assertEquals(decoded.flags.compressed, 1);
assertEquals(decoded.flags.version, 2);
assertEquals(decoded.payloadSize, 1024);

Type Parameters

T extends BitSchema

Parameters

schema: T

Object mapping field names to bit counts (1-32)

Return Type

A Coder that encodes/decodes bit-packed structures

Throws

Error

If any bit count is not an integer between 1-32

Error

If total bits is not a multiple of 8