Skip to content

Bitflag attribute macro for Rust enums

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

GrayJack/bitflag-attr

Repository files navigation

bitflag-attr

Rust Latest version Documentation License

This is a proc-macro Rust crate that allows to turn a C-like enum into a bitflag types with an ergonomic end-user API.

You can use this crate to:

  • Provide more user-friendly bindings to C APIs where flags may or may not be fully known in advance.
  • Generate efficient options types with string parsing and formatting support.

You can't use this crate to:

  • Guarantee only bits corresponding to defined flags will ever be set. bitflag-attr allows access to the underlying bits type so arbitrary bits may be set.

  • Define bitfields. bitflag-attr only generates types where set bits denote the presence of some combination of flags.

  • Documentation

Usage

Add this to your Cargo.toml:

[dependencies]
bitflag-attr = "0.9.0"

and this to your source code:

use bitflag_attr::bitflag;

Quick Example

Generate a flags structure:

use bitflag_attr::bitflag;

#[bitflag(u32)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
enum Flags {
    /// The value `A`, at bit position `0`.
    A = 0b00000001,
    /// The value `B`, at bit position `1`.
    B = 0b00000010,
    /// The value `C`, at bit position `2`.
    C = 0b00000100,

    /// The combination of `A`, `B`, and `C`.
    ABC = A | B | C,
}

fn main() {
    let e1 = Flags::A | Flags::C;
    let e2 = Flags::B | Flags::C;
    assert_eq!((e1 | e2), Flags::ABC);   // union
    assert_eq!((e1 & e2), Flags::C);     // intersection
    assert_eq!((e1 - e2), Flags::A);     // set difference
    assert_eq!(!e2, Flags::A);           // set complement
}

If you don't want Debug trait to be generated, you can simply not define it on the derive attribute.

use bitflag_attr::bitflag;

#[bitflag(u32)]
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
enum Flags {
    /// The value `A`, at bit position `0`.
    A = 0b00000001,
    /// The value `B`, at bit position `1`.
    B = 0b00000010,
    /// The value `C`, at bit position `2`.
    C = 0b00000100,

    /// The combination of `A`, `B`, and `C`.
    ABC = A | B | C,
}

Features

  • Use enum native syntax to define individual known flags
  • Discriminant values must be defined
  • Generated end-user API almost entirely the same to bitflags crate
  • Most of the generated type-associated API is const-compatible (entirely if const-mut-ref feature flag enabled)
  • Debug formatter outputs both the binary representation and named flag representation
  • Optional support for serialization with the serde feature flag
  • Compatible with #[no_std]

Implemented traits

The macro requires that Clone and Copy are derived.

The macro will also implement some traits for bitwise operations and formatting.

  • core::ops::Not
  • core::ops::BitAnd
  • core::ops::BitOr
  • core::ops::BitXor
  • core::ops::BitAndAssign
  • core::ops::BitOrAssign
  • core::ops::BitXorAssign
  • core::ops::Sub
  • core::ops::SubAssign
  • core::fmt::Debug (if on the derive macro list)
  • core::fmt::Binary
  • core::fmt::UpperHex
  • core::fmt::LowerHex
  • core::fmt::Octal
  • core::str::FromStr
  • core::iter::Extend
  • core::iter::FromIterator
  • core::iter::IntoIterator (for the type and reference)
  • From

If the Debug trait is defined in the #[derive(...)] attribute. The macro will produce a custom implementation instead of the one Rust std produces

There is a opt-in crate feature serde that generate a parsing error type and implements the traits:

  • serde::Serialize
  • serde::Deserialize

The custom implementation for Serialize and Deserialize will be generated only if those traits are in the #[derive(...)] attribute list (similar how the Debug works).

Note: This crate does not import/re-export serde traits, your project MUST have serde as dependency.

Const mut ref

Most of the associated function generated for the flags type are const-compatible, with exceptions with the one that takes &mut self.

If you are on Rust version 1.83.0 or superior, you can enable the const-mut-ref feature flag to make those function to also be const-compatible.

Alternatives

Rust Version Support

The minimum supported Rust version is documented in the Cargo.toml file. This may be bumped in minor releases as necessary.

About

Bitflag attribute macro for Rust enums

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages