Skip to content

Commit d28900d

Browse files
committed
📝 Docs and cfg attr for default
1 parent afa7fd8 commit d28900d

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

README.md

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
Procedural macro for bitfields that allows specifying bitfields as structs.
77
As this library provides a procedural macro, it has no runtime dependencies and works for `no-std` environments.
88

9-
- Supports bool flags, raw integers, and every custom type convertible into integers (structs/enums)
109
- Ideal for driver/OS/embedded development (defining HW registers/structures)
10+
- Supports bool flags, integers, and custom types convertible into integers (structs/enums)
1111
- Generates minimalistic, pure, safe rust functions
1212
- Compile-time checks for type and field sizes
13-
- Rust-analyzer friendly (carries over documentation to accessor functions)
13+
- Rust-analyzer/docrs friendly (carries over docs to accessor functions)
1414
- Exports field offsets and sizes as constants (useful for const asserts)
15-
- Generation of `fmt::Debug` and `Default`
16-
- Optional generation of `defmt::Format`
15+
- Generation of `Default`, `fmt::Debug`, or `defmt::Format` traits
16+
- Custom internal representation (endianness)
1717

1818
## Usage
1919

@@ -254,7 +254,7 @@ struct Nested {
254254
}
255255
```
256256

257-
## Bit Order
257+
## Field Order
258258

259259
The optional `order` macro argument determines the layout of the bits, with the default being
260260
Lsb (least significant bit) first:
@@ -264,15 +264,14 @@ use bitfield_struct::bitfield;
264264

265265
#[bitfield(u8, order = Lsb)]
266266
struct MyLsbByte {
267-
/// The first field occupies the least significant bits
267+
/// The first field occupies the *least* significant bits
268268
#[bits(4)]
269269
kind: usize,
270270
system: bool,
271271
#[bits(2)]
272272
level: usize,
273273
present: bool
274274
}
275-
276275
let my_byte_lsb = MyLsbByte::new()
277276
.with_kind(10)
278277
.with_system(false)
@@ -293,15 +292,14 @@ use bitfield_struct::bitfield;
293292

294293
#[bitfield(u8, order = Msb)]
295294
struct MyMsbByte {
296-
/// The first field occupies the most significant bits
295+
/// The first field occupies the *most* significant bits
297296
#[bits(4)]
298297
kind: usize,
299298
system: bool,
300299
#[bits(2)]
301300
level: usize,
302301
present: bool
303302
}
304-
305303
let my_byte_msb = MyMsbByte::new()
306304
.with_kind(10)
307305
.with_system(false)
@@ -369,7 +367,7 @@ let my_be_bitfield = MyBeBitfield::new()
369367
assert_eq!(my_be_bitfield.into_bits().to_be_bytes(), [0x23, 0x41]);
370368
```
371369

372-
## `fmt::Debug` and `Default`
370+
## Automatic Trait Implementations
373371

374372
This macro automatically creates a suitable `fmt::Debug` and `Default` implementations similar to the ones created for normal structs by `#[derive(Debug, Default)]`.
375373
You can disable this with the extra `debug` and `default` arguments.
@@ -397,9 +395,10 @@ let val = CustomDebug::default();
397395
println!("{val:?}")
398396
```
399397

400-
## `defmt::Format`
398+
### Support for `defmt::Format`
401399

402-
This macro can automatically implement a `defmt::Format` that mirrors the default `fmt::Debug` implementation by passing the extra `defmt` argument. This implementation requires the defmt crate to be available as `defmt`, and has the same rules and caveats as `#[derive(defmt::Format)]`.
400+
This macro can automatically implement a `defmt::Format` that mirrors the default `fmt::Debug` implementation by passing the extra `defmt` argument.
401+
This implementation requires the defmt crate to be available as `defmt`, and has the same rules and caveats as `#[derive(defmt::Format)]`.
403402

404403
```rust
405404
use bitfield_struct::bitfield;
@@ -408,4 +407,17 @@ use bitfield_struct::bitfield;
408407
struct DefmtExample {
409408
data: u64
410409
}
411-
````
410+
```
411+
412+
### Conditionally Enable `Debug`/`Default`/`defmt::Format`
413+
414+
Instead of booleans, you can specify `cfg(...)` attributes for `debug`, `default` and `defmt`:
415+
416+
```rust
417+
use bitfield_struct::bitfield;
418+
419+
#[bitfield(u64, debug = cfg(test), default = cfg(feature = "foo"))]
420+
struct CustomDebug {
421+
data: u64
422+
}
423+
```

src/lib.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,10 @@ fn bitfield_inner(args: TokenStream, input: TokenStream) -> syn::Result<TokenStr
116116

117117
let defaults = members.iter().map(Member::default);
118118

119-
let impl_default = default.then(|| {
119+
let impl_default = default.cfg().map(|cfg| {
120+
let attr = cfg.map(|cfg| quote!(#[cfg(#cfg)]));
120121
quote! {
122+
#attr
121123
impl Default for #name {
122124
fn default() -> Self {
123125
Self::new()
@@ -755,8 +757,8 @@ enum Order {
755757

756758
#[derive(Debug, Clone)]
757759
enum Enable {
758-
Yes,
759760
No,
761+
Yes,
760762
Cfg(TokenStream),
761763
}
762764
impl Enable {
@@ -797,7 +799,7 @@ struct Params {
797799
bits: usize,
798800
debug: Enable,
799801
defmt: Enable,
800-
default: bool,
802+
default: Enable,
801803
order: Order,
802804
conversion: bool,
803805
}
@@ -820,7 +822,7 @@ impl Parse for Params {
820822
bits,
821823
debug: Enable::Yes,
822824
defmt: Enable::No,
823-
default: true,
825+
default: Enable::Yes,
824826
order: Order::Lsb,
825827
conversion: true,
826828
};
@@ -846,7 +848,7 @@ impl Parse for Params {
846848
ret.defmt = input.parse()?;
847849
}
848850
"default" => {
849-
ret.default = syn::LitBool::parse(input)?.value;
851+
ret.default = input.parse()?;
850852
}
851853
"order" => {
852854
ret.order = match syn::Ident::parse(input)?.to_string().as_str() {

0 commit comments

Comments
 (0)