Comments (5)
Good idea!
I think this could be easily implementable through #[derive(BitfieldSpecifier)]
on structs that implements the Specifier
trait similar as to how it is done for enums. The rest would just work out of the box if I imagine this correctly.
For this to work for header bitfield structs that are larger than 128 bits we would need to define bit specifiers for that region. For example we could use [u8; N]
with N >= 33
for that:
impl modular_bitfield::Specifier for B129 {
const BITS: usize = 129;
type Base = [u8; 33];
type Face = [u8; 33];
}
etc.
from modular-bitfield.
Another idea would be to use the derive macro to mark some structs as bitfield specifiers just as it is already been done for enums.
Example
#[derive(BitfieldSpecifier)]
struct Header {
a: B2,
b: B3,
}
Internally this struct will be of size sizeof<u8> + sizeof<u8>
since both fields would just be translated to their respective underlying base type which is u8
for B2
and B3
. This implies that B2
and B3
no longer can be represented as empty enum types but need to wrap or match their base type to capture the actual value later.
Unlike #[bitfield]
annotated structs there is no longer a need for generating getters and setters since making the fields simply public is enough to ensure safe access.
/// Uses 3 bits in total.
#[derive(BitfieldSpecifier)]
struct HeaderHeader {
x: B1,
y: B2,
}
/// Uses 5 bits in total.
#[derive(BitfieldSpecifier)]
struct Header1 {
a: B2,
b: B3,
}
/// Uses 8 bits in total.
#[derive(BitfieldSpecifier)]
struct Header2 {
hh: HeaderHeader,
a: B2,
b: B3,
}
/// Uses only header 1.
#[bitfield]
struct BaseA {
h1: Header1,
c: B11,
}
/// Uses only Header2.
///
/// Note that Header2 uses HeaderHeader internally.
#[bitfield]
struct BaseB {
h: Header2,
c: B19,
}
/// Uses all headers.
///
/// Note that this is effectively using HeaderHeader twice.
#[bitfield]
struct BaseC {
h1: Header1,
h2: Header2,
h3: HeaderHeader,
a: B7,
b: B9,
}
The next code snippets demonstrates what code arround a bitfield specifier struct is generated:
/// Uses 3 bits in total.
#[derive(BitfieldSpecifier)]
struct Header {
x: B1,
y: B2,
}
impl modular_bitfield::Specifier for Header {
const BITS: usize =
<B1 as modular_bitfield::Specifier>::BITS
+ <B2 as modular_bitfield::Specifier>::BITS;
type Base = <[(); <B1 as modular_bitfield::Specifier>::BITS
+ <B2 as modular_bitfield::Specifier>::BITS] as modular_bitfield::SpecifierBase>::Base;
type Face = Header;
}
impl modular_bitfield::FromBits<<Header as modular_bitfield::Specifier>::Base> for Header {
fn from_bits(bits: modular_bitfield::Bits<<Header as modular_bitfield::Specifier>::Base>) -> Self {
// To be determined ...
}
}
impl modular_bitfield::IntoBits<<Header as modular_bitfield::Specifier>::Base> for Header {
fn into_bits(self) -> modular_bitfield::Bits<<Header as modular_bitfield::Specifier>::Base> {
// To be determined ...
}
}
from modular-bitfield.
With the most recent improvements in the backend of the modular_bitfield
crate I now see a more or less easy solution towards supporting structs in structs.
For this we need to add another attribute #[specifier]
to the #[bitfield]
proc. macro attribute.
Using the specifier
attribute allows for bitfield structs that also implement the Specifier
trait, also it allows them to not have bit widths divisible by 8. We could introduce yet another attribute to control this aspect for non-specifier bitfields as well but maybe better for a follow-up PR.
The following example demonstrates what code needs to be generated for a situation where we have a Header
bitfield that also is a specifier:
#[bitfield(specifier = true)]
pub struct Header {
a: B2,
b: B3,
}
#[bitfield]
pub struct Generated {
pub header: Header,
pub rest: B3, // To make it divisible by 8.
}
This would generate approximately this code for the Specifier
trait implementation:
impl modular_bitfield::Specifier for Header {
const BITS: usize = 5;
type Bytes = u8;
type InOut = Self;
fn into_bytes(
value: Self::InOut,
) -> Result<Self::Bytes, OutOfBounds> {
Ok(u8::from_le_bytes(value.data))
}
fn from_bytes(
bytes: Self::Bytes,
) -> Result<Self::InOut, InvalidBitPattern<Self::Bytes>>
{
if bytes > ((0x01 << Self::BITS) - 1) {
return Err(InvalidBitPattern::new(bytes))
}
Ok(Self {
data: bytes.to_le_bytes(),
})
}
}
from modular-bitfield.
WIP PR: #29
from modular-bitfield.
Closed as #29 has just been merged.
from modular-bitfield.
Related Issues (20)
- Support for `to_u32()` conversion to `u32` and similar
- #[bitfield] on empty struct causes compilation error
- Feature Request: Ability to specify default value for field
- Disjoint Fields HOT 1
- Implement serde derives replacement HOT 2
- Feature request: Array support HOT 3
- Into<uN> and TryFrom<uN> for uN bitfields HOT 2
- `with_*` methods should have `#[must_use]` annotation HOT 2
- Help: CheckFillsUnalignedBits unsatisfied HOT 2
- Support rust union structs HOT 1
- Feature request: Allow naming fields "Bytes" HOT 1
- Question: Array of bitfields HOT 1
- #[repr(...)] for unfilled bitfields?
- Generic structs not supported HOT 7
- [Question] Polymorphic bitfileds HOT 1
- Support for byte arrays
- `#[non_exhaustive]` enum support HOT 9
- const fn support for getters (and setters if possible) HOT 1
- How to implement signed 10 bit number? HOT 8
- [Feature Request] Better Note for (Size % 8)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from modular-bitfield.