Code Monkey home page Code Monkey logo

Comments (5)

Robbepop avatar Robbepop commented on August 16, 2024

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.

Robbepop avatar Robbepop commented on August 16, 2024

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.

Robbepop avatar Robbepop commented on August 16, 2024

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.

Robbepop avatar Robbepop commented on August 16, 2024

WIP PR: #29

from modular-bitfield.

Robbepop avatar Robbepop commented on August 16, 2024

Closed as #29 has just been merged.

from modular-bitfield.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.