dzamlo / rust-bitfield

This crate provides macros to generate bitfield-like struct.
Apache License 2.0
157 stars 19 forks source link

bitfield should create constructor methods #18

Closed asomers closed 2 months ago

asomers commented 6 years ago

The bitfield method only creates getter and accessor methods. It would be great if it could create constructors too. For example,

bitfield! {
    struct Foo(u16);
    u8;
    a, _: 7, 0;
    b, _: 15, 8;
}

should have something like the following in its expansion:

impl Foo {
    fn new(a: u8, b: u8) -> Self {
        Foo(((b as u16) << 8) | (a as u16))
    }
}
PokeJofeJr4th commented 2 months ago

I could probably do something like this but it would be a lot of code. My plan would be to use setters instead of direct bit manipulation. Using direct bit manipulation looks like it would duplicate a lot more code to parse out the ranges and everything.

I'd expect the compiler/LLVM to generate something like the example in this issue even if we express it using setters.

I'm also not sure what to do if you'd want multiple constructors with different subsets of the fields, since I don't think it's possible to compare identifiers in macros.

@dzamlo thoughts?

dzamlo commented 2 months ago

I agree on reusing existing setters.

On the multiple constructors question, I don't think doing more than one constructor with every field that has a setter is worth it.

PokeJofeJr4th commented 2 months ago

I don't think we're on the same page there. One example is the ArrayBitField struct from the tests:

    u32;
    foo1, set_foo1: 0, 0;
    foo2, set_foo2: 7, 0;
    foo3, set_foo3: 8, 1;
    foo4, set_foo4: 19, 4;
    i32;
    signed_foo1, set_signed_foo1: 0, 0;
    signed_foo2, set_signed_foo2: 7, 0;
    signed_foo3, set_signed_foo3: 8, 1;
    signed_foo4, set_signed_foo4: 19, 4;
    u128, u128_getter, set_u128: 19, 4;

I'd like to be able to generate 3 different constructors if I want: for the foo, signed_foo, and u128 field sets. I've got a working version with all fields locally, but not selecting specific fields.