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 (u8tou128).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
| Macro | Storage | Max Width | Best For… |
|---|---|---|---|
bitstruct! | u8-u128 | 128 bits | Hardware registers, CPU-native bitmasks. |
bytestruct! | [u8; 1-16] | 128 bits | Smaller network headers, dense buffers. |
byteval! | [u8; 1-16] | 128 bits | Semantic 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 ifvaloverflows the allocated bits. -
try_set_field(val): ReturnsResult<(), BitstructError>ifvalis too large. -
try_from_bits(val): Validates that raw bits correspond to a definedbitenum!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.
Defaultinitialization 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.
| Category | Hardware Alignment | Overhead 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 Enum | 0.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§
- Bitstruct
Error - Error types returned by strict data structures when encountering invalid operations.