macro_rules! bitfield { ($(#[$attribute:meta])* pub struct $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* struct $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($($type:tt)*); $(impl $trait:ident$({$($trait_arg:tt)*})?;)+ no default BitRange; $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); no default BitRange; $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; impl $trait:ident$({$($trait_arg:tt)*})?; $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; $($rest:tt)*) => { ... }; ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); $($rest:tt)*) => { ... }; }
Expand description
Combines bitfield_bitrange
and bitfield_fields
.
The syntax of this macro is the syntax of a tuple struct, including attributes and
documentation comments, followed by a semicolon, some optional elements, and finally the fields
as described in the bitfield_fields
documentation.
The first optional element is no default BitRange;
. With that, no implementation of
BitRange
will be generated.
The second optional element is a set of lines of the form impl <Trait>;
. The following traits are supported:
Debug
; This will generate an implementation offmt::Debug
with thebitfield_debug
macro.BitAnd
,BitOr
,BitXor
; These will generate implementations of the relevantops::Bit___
andops::Bit___Assign
traits.new
; This will generate a constructor that calls all of the bitfield’s setter methods with an argument of the appropriate typenew{constructor_name(setter_name: setter_type, ...)}
; This will generate a constructor that calls a given subset of the bitfield’s setter methods
The difference with calling those macros separately is that bitfield_fields
is called
from an appropriate impl
block. If you use the non-slice form of bitfield_bitrange
, the
default type for bitfield_fields
will be set to the wrapped fields.
See the documentation of these macros for more information on their respective syntax.
§Example
bitfield!{
pub struct BitField1(u16);
impl Debug;
// The fields default to u16
field1, set_field1: 10, 0;
pub field2, _ : 12, 3;
}
or with a custom BitRange
and BitRangeMut
implementation :
bitfield!{
pub struct BitField1(u16);
no default BitRange;
impl Debug;
impl BitAnd;
u8;
field1, set_field1: 10, 0;
pub field2, _ : 12, 3;
}
impl BitRange<u8> for BitField1 {
fn bit_range(&self, msb: usize, lsb: usize) -> u8 {
let width = msb - lsb + 1;
let mask = (1 << width) - 1;
((self.0 >> lsb) & mask) as u8
}
}
impl BitRangeMut<u8> for BitField1 {
fn set_bit_range(&mut self, msb: usize, lsb: usize, value: u8) {
self.0 = (value as u16) << lsb;
}
}