Skip to content

Commit

Permalink
Allow creating bitfield structs with arbitrary visibilities
Browse files Browse the repository at this point in the history
  • Loading branch information
ADSteele916 authored and dzamlo committed Sep 7, 2024
1 parent bd0aebd commit d60a1c0
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 27 deletions.
42 changes: 18 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,28 +807,22 @@ macro_rules! bitfield_bitrange {
/// ```
#[macro_export(local_inner_macros)]
macro_rules! bitfield {
($(#[$attribute:meta])* pub struct $($rest:tt)*) => {
bitfield!($(#[$attribute])* (pub) struct $($rest)*);
};
($(#[$attribute:meta])* struct $($rest:tt)*) => {
bitfield!($(#[$attribute])* () struct $($rest)*);
};
// Force `impl <Trait>` to always be after `no default BitRange` it the two are present.
// This simplify the rest of the macro.
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($($type:tt)*); $(impl $trait:ident$({$($trait_arg:tt)*})?;)+ no default BitRange; $($rest:tt)*) => {
bitfield!{$(#[$attribute])* ($($vis)*) struct $name($($type)*); no default BitRange; $(impl $trait$({$($trait_arg)*})?;)* $($rest)*}
($(#[$attribute:meta])* $vis:vis struct $name:ident($($type:tt)*); $(impl $trait:ident$({$($trait_arg:tt)*})?;)+ no default BitRange; $($rest:tt)*) => {
bitfield!{$(#[$attribute])* $vis struct $name($($type)*); no default BitRange; $(impl $trait$({$($trait_arg)*})?;)* $($rest)*}
};

// If we have `impl <Trait>` without `no default BitRange`, we will still match, because when
// we call `bitfield_bitrange`, we add `no default BitRange`.
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => {
($(#[$attribute:meta])* $vis:vis struct $name:ident([$t:ty]); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => {
bitfield_impl!{$trait$({$($trait_arg)*})? for struct $name([$t]); $($rest)*}

bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
};
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; $($rest:tt)*) => {
($(#[$attribute:meta])* $vis:vis struct $name:ident([$t:ty]); no default BitRange; $($rest:tt)*) => {
$(#[$attribute])*
$($vis)* struct $name<T>(pub T);
$vis struct $name<T>(pub T);

//impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
// bitfield_fields!{$($rest)*}
Expand All @@ -840,37 +834,37 @@ macro_rules! bitfield {
bitfield_fields!{only setter; $($rest)*}
}
};
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); $($rest:tt)*) => {
($(#[$attribute:meta])* $vis:vis struct $name:ident([$t:ty]); $($rest:tt)*) => {
bitfield_bitrange!(struct $name([$t]));
bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
};

// The only difference between the MSB0 version anf the non-MSB0 version, is the BitRange
// implementation. We delegate everything else to the non-MSB0 version of the macro.
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); no default BitRange; $($rest:tt)*) => {
bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
($(#[$attribute:meta])* $vis:vis struct $name:ident(MSB0 [$t:ty]); no default BitRange; $($rest:tt)*) => {
bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
};
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
($(#[$attribute:meta])* $vis:vis struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
bitfield_bitrange!(struct $name(MSB0 [$t]));
bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
bitfield!{$(#[$attribute])* $vis struct $name([$t]); no default BitRange; $($rest)*}
};

($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => {
($(#[$attribute:meta])* $vis:vis struct $name:ident($t:ty); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => {
bitfield_impl!{$trait$({$($trait_arg)*})? for struct $name($t); $($rest)*}

bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
bitfield!{$(#[$attribute])* $vis struct $name($t); no default BitRange; $($rest)*}
};
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; $($rest:tt)*) => {
($(#[$attribute:meta])* $vis:vis struct $name:ident($t:ty); no default BitRange; $($rest:tt)*) => {
$(#[$attribute])*
$($vis)* struct $name(pub $t);
$vis struct $name(pub $t);

impl $name {
bitfield_fields!{$t; $($rest)*}
}
};
($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); $($rest:tt)*) => {
($(#[$attribute:meta])* $vis:vis struct $name:ident($t:ty); $($rest:tt)*) => {
bitfield_bitrange!(struct $name($t));
bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
bitfield!{$(#[$attribute])* $vis struct $name($t); no default BitRange; $($rest)*}
};
}

Expand Down
6 changes: 3 additions & 3 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ fn test_arraybitfield2() {
}

bitfield! {
struct ArrayBitfieldMsb0(MSB0 [u8]);
pub(self) struct ArrayBitfieldMsb0(MSB0 [u8]);
impl Debug;
u32;
foo1, set_foo1: 0, 0;
Expand Down Expand Up @@ -865,7 +865,7 @@ fn test_arraybitfield_constructor() {

mod some_module {
bitfield! {
pub struct PubBitFieldInAModule(u32);
pub(super) struct PubBitFieldInAModule(u32);
impl Debug;
/// Attribute works on pub fields
pub field1, set_field1: 1;
Expand Down Expand Up @@ -1061,7 +1061,7 @@ mod test_no_default_bitrange {
}

bitfield! {
pub struct BitField2(u16);
pub(crate) struct BitField2(u16);
no default BitRange;
u8;
field1, set_field1: 10, 0;
Expand Down

0 comments on commit d60a1c0

Please sign in to comment.