| Crates.io | bitfld |
| lib.rs | bitfld |
| version | 0.1.7 |
| created_at | 2025-02-16 23:34:24.483732+00 |
| updated_at | 2025-02-17 05:48:11.299429+00 |
| description | Ergonomic, no-std specification of bitfield layouts |
| homepage | |
| repository | https://github.com/joshuaseaton/bitfld |
| max_upload_size | |
| id | 1558251 |
| size | 37,016 |
bitfld is a no-std crate for ergonomically specifying layouts of bitfields
over integral types. While the aim is to be general-purpose, the imagined user
is a systems programmer uncomfortably hunched over an architectural manual or
hardware spec, looking to transcribe register layouts into Rust with minimal
fuss.
The heavy lifting is done by the layout! procedural macro. Care
is taken to generate readable and efficient code. The zerocopy
crate is further leveraged for safe and efficient transmutation between integral
values and custom bitfield representations.
Copy, CloneEq, PartialEqDefaultFrom over the base typeDeref and DerefMut with a target of the underlying base typeDebug, Display, Binary, LowerHex, UpperHex, Octalnew() respecting
reserved-as values and default() respecting both;For more detail, see layout!.
use bitfld::{bitfield_repr, layout};
#[bitfield_repr(u8)]
pub enum CustomFieldRepr {
Option1 = 0xa,
Option2 = 0xf,
}
layout!({
pub struct Example(u32);
{
let foo: Bits<21, 14>;
let custom: Bits<13, 10, CustomFieldRepr>;
let bar: Bits<9, 8> = 0b11;
let baz: Bit<7>;
let frob: Bits<6, 4>;
let _: Bits<3, 2> = 1;
let _: Bits<1, 0>;
}
});
fn main() {
let example = *Example::default()
.set_custom(CustomFieldRepr::Option2)
.set_frob(0x7);
assert_eq!(example.foo(), 0);
assert_eq!(example.custom().unwrap(), CustomFieldRepr::Option2);
assert_eq!(example.bar(), 0b11);
assert_eq!(example.baz(), false);
assert_eq!(example.frob(), 0x7);
assert_eq!(*example & 0b1100, 0b0100);
// Will print: `Example { custom: Option2, foo: 0x0, bar: 0x3, baz: false, frob: 0xa }`
println!("{example}");
// Or iterate over all fields and and print them individually.
for (value, metadata) in example {
println!("{}: {:x}", metadata.name, value);
}
}
bitfield_repr is an attribute that is syntactic sugar for deriving
repr(X) and the handful of traits expected of a custom field representation.
There are already a handful out there, so why this one too? It is the author's opinion that none of those at the time of writing this offer all of the above features (e.g., around reserved semantics or boilerplate-free, custom field representations) or the author's desired ergonomics around register modeling. For example, some constrain field specification by bit width instead of by an explicit bit range, which is not how registers are commonly described in official references (plus, the author surely can't trust himself to do mental math like that).