Skip to main content

Crate bitcraft

Crate bitcraft 

Source
Expand description

§bitcraft

The zero-cost, hardware-aligned bitfield and enumeration engine for Rust.

bitcraft is a high-performance declarative macro library designed for systems where every bit counts. It allows defining types where logical fields map directly to bit-ranges with zero runtime overhead.

§Core Macros

  • bitstruct!: Define a bit-packed struct over a base integer (u8 to u128).
  • bytestruct!: Define a byte-aligned struct over a fixed-size array ([u8; 1-16]).
  • byteval!: A shorthand for “NewType” byte-array wrappers (e.g., 24-bit IDs) up to 16 bytes.
  • bitenum!: Define strongly-typed, zero-cost enumerations for use within bitfields.

§🛠️ Choosing the Right Macro

MacroStorageMax WidthBest For…
bitstruct!u8-u128128 bitsHardware registers, CPU-native bitmasks.
bytestruct![u8; 1-16]128 bitsSmaller network headers, dense buffers.
byteval![u8; 1-16]128 bitsSemantic NewTypes (e.g. Id24, MacAddr).

§⚠️ Error Handling & Validation

bitcraft provides both “failable” and “panicking” APIs for field updates:

  • set_field(val): Panics in debug mode if val overflows the allocated bits.

  • try_set_field(val): Returns Result<(), BitstructError> if val is too large.

  • try_from_bits(val): Validates that raw bits correspond to a defined bitenum! variant.

  • No Manual Derives: All generated types automatically implement Default (zero-initialization).

§🔌 No-Std Support

bitcraft is #![no_std] by default and does not require an allocator. It is perfectly suited for bare-metal kernels, embedded firmware, and high-performance drivers.

§🛡️ Safety & Memory Layout

bitcraft enforces strict memory layouts to ensure predictability across FFI boundaries and hardware interfaces:

  • Transparent Representation: All generated structs use #[repr(transparent)], guaranteeing they have the exact same size and alignment as their underlying primitive or array.
  • LSB-First Packing: Bits are filled from the least significant bit (index 0) upward.
  • Memory Safety: While the internal helpers use bit-manipulation, the public API is entirely safe. Default initialization always results in zeroed memory.

§Visual Packing Example (u8)

MSB (Bit 7)                          LSB (Bit 0)
 +---+---+---+---+---+---+---+---+
 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |  <-- Physical Bits
 +---+---+---+---+---+---+---+---+
 |  Field B (5)  |   Field A (3) |  <-- Logical Fields
 +---+---+---+---+---+---+---+---+

§🚀 Performance & Benchmarks

bitcraft is built with “Mechanical Sympathy” for Little-Endian systems. All operations are const fn and utilize LLVM’s constant-folding to eliminate branching for constant-width fields.

CategoryHardware AlignmentOverhead vs Manual Code
bitstruct!Word-Aligned (u8-u128)0.92x - 0.98x (Faster)
bytestruct!Array-Backed ([u8; N])~2.5x
byteval!Odd-Width IDs (24-bit)0.94x - 0.97x (Faster)
bitenum!Specialized Enum0.97x - 0.99x (Parity)

Benchmarks performed on a 1B iteration loop. “Faster than manual” is achieved through instruction fusion and aligned register loading.

§🧩 Showcasing Interoperability

bitcraft is designed for high-performance systems where data must move seamlessly between the CPU, the network, and other languages.

§Zero-Copy Network & Buffer Parsing

Using the bytemuck crate, you can cast raw byte slices directly into typed bitfields with zero memory movement:

bitstruct! {
    pub struct EthernetHeader(u16) {
        pub protocol: u16 = 16,
    }
}

let data = [0x08, 0x00]; // IPv4 EtherType
// No allocation, no parsing loop, just a typed overlay.
let header: &EthernetHeader = bytemuck::from_bytes(&data);

§Foreign Function Interface (C-ABI)

Every bitstruct! and bytestruct! is marked #[repr(transparent)]. This guarantees that its memory layout is identical to the underlying primitive, making it safe to pass directly to C/C++ libraries.

bitstruct! {
    pub struct FfiFlags(u8) {
        pub readable: bool = 1,
        pub writable: bool = 1,
    }
}

unsafe extern "C" {
    // Correctly passes as a 'uint8_t' in C
    fn c_handle_flags(flags: FfiFlags);
}

§Hardware Register Access (MMIO)

Because bitcraft uses LSB-first mapping, your logical field definitions match the physical bit-offsets used in hardware datasheets for Little-Endian systems (x86, ARM).

bitstruct! {
    pub struct StatusRegister(u32) {
        pub ready: bool = 1,
        pub error_code: u8 = 4,
        pub reserved: u32 = 27,
    }
}

// let reg = StatusRegister::from_bits(mmio_addr.read_volatile());

§Usage Example

use bitcraft::{bitstruct, bitenum};

bitenum! {
    /// Represent the state of an active process.
    pub enum ProcessState(2) {
        IDLE = 0,
        RUNNING = 1,
        BLOCKED = 2,
    }
}

bitstruct! {
    /// A 16-bit packed struct.
    pub struct ProcessDescriptor(u16) {
        pub is_privileged: bool = 1,       // Bit 0
        pub priority: u8 = 3,              // Bits 1-3
        pub memory_pages: u16 = 10,        // Bits 4-13
        pub state: ProcessState = 2,       // Bits 14-15
    }
}

fn main() {
    let mut desc = ProcessDescriptor::default()
        .with_is_privileged(true)
        .with_priority(5)
        .with_memory_pages(1023)
        .with_state(ProcessState::RUNNING);

    assert_eq!(desc.priority(), 5);
    assert_eq!(desc.state(), ProcessState::RUNNING);

    desc.set_state(ProcessState::BLOCKED);
    assert_eq!(desc.state(), ProcessState::BLOCKED);
}

Macros§

bitenum
A declarative macro for generating zero-cost bitenums.
bitstruct
A declarative macro for generating zero-cost, strictly packed bitfields.
bytestruct
A unique declarative macro for generating bitfields backed by fixed-size byte arrays.
byteval
A unique shorthand macro for creating “NewType” byte-array wrappers with a primary value field.

Enums§

BitstructError
Error types returned by strict data structures when encountering invalid operations.