Skip to content

Defaults and const for custom types #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 27, 2023
Merged

Defaults and const for custom types #16

merged 6 commits into from
Jun 27, 2023

Conversation

wrenger
Copy link
Owner

@wrenger wrenger commented May 22, 2023

As discussed in #15, this PR adds support for default parameters. This is different from the standard library Default trait as the bitfields are usually also used in const-eval contexts.

The downside of const-ness is that custom types can no longer rely on the (non-const) From/Into traits and now require explicit conversion functions in the bits attribute.

Here is an example that uses defaults and custom types:

#[bitfield(u16)]
#[derive(PartialEq, Eq)]
struct MyBitfield {
    /// Interpreted as 1-bit flag, with custom default
    #[bits(default = true)]
    flag: bool,
    /// Supports any type, with default/to/from expressions (that are const eval)
    /// - into/from call #ty::into_bits/#ty::from_bits if nothing else is specified
    #[bits(13, default = CustomEnum::B, from = CustomEnum::my_from_bits)]
    custom: CustomEnum,
    // Padding with default
    #[bits(2, default = 0b10)]
    __: (),
}

/// A custom enum
#[derive(Debug, PartialEq, Eq)]
#[repr(u16)]
enum CustomEnum {
    A = 0,
    B = 1,
    C = 2,
}
impl CustomEnum {
    // This has to be const eval
    const fn into_bits(self) -> u16 {
        self as _
    }
    const fn my_from_bits(value: u16) -> Self {
        match value {
            0 => Self::A,
            1 => Self::B,
            _ => Self::C,
        }
    }
}

// Uses defaults
let val = MyBitfield::new();

assert_eq!(val.flag(), true);
assert_eq!(val.custom(), CustomEnum::B);
assert_eq!(val.0 >> 14, 0b10); // padding

@wrenger wrenger force-pushed the explicit_conversion branch 2 times, most recently from d10719f to a4f9ad8 Compare May 26, 2023 21:13
@wrenger wrenger mentioned this pull request May 26, 2023
@wrenger wrenger force-pushed the explicit_conversion branch from ec920c0 to 6317fda Compare June 5, 2023 19:01
wrenger and others added 6 commits June 27, 2023 21:52
The downside of const-ness is that custom types cannot rely
on the (non-const) From/Into traits anymore and now require
explicit conversion functions.
They do not require the default argument anymore and instead
are initialized with zero (passed through `from`)
Now, from and into default to $ty::from_bits and $ty::into_bits.
@wrenger wrenger force-pushed the explicit_conversion branch from 25d7358 to b69d9ee Compare June 27, 2023 19:53
@wrenger wrenger merged commit 7651a05 into main Jun 27, 2023
@wrenger wrenger deleted the explicit_conversion branch June 27, 2023 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant