🚧 **Warning: Experimental Crate!** 🚧
This crate is currently in **beta** and **experimental**.
It is subject to **breaking changes** in future releases.
Use it at your own risk, and keep in mind that the API may change in future versions.
# Hexga BitFlags
A bitflags crate, mainly inspired by [enumflags2](https://crates.io/crates/enumflags2).
Provide a `#[bit_index]` attribute macro that can be applied to **enum** `X` to automatically generate a corresponding **bitflags struct** `XFlags` and implement various bitwise operations, conversions, and utility methods for working with sets of enum variants as bitflags.
The `#[bit_index]` macro interprets each enum variant as defining the position of a bit in the generated flags type.
## Features
- **Automatic Bitflag Generation:** Annotate your enum `X` with `#[bit_index]` to generate a corresponding `XFlags` structure with the associated constant.
- **Custom Discriminant Value:** Supports enums with explicit discriminants and non-contiguous values.
- **Type Safe Flags:** The `Flags` structure contains only valid bit. Unused `enum` bit index will always be zero, when when calling not `!flags`.
- **Common Binary Operations:** Use `|`, `&`, `^`, and `!` operators directly on enum variants and the bitflags structure.
- **Iteration:** iterate over the enabled bits or retrieve enum variants from a flag set.
- **Serde Support:** Optional serialization/deserialization via the `serde` feature.
- **Simple API:** Includes methods for insertion, remove, toggling bits...
## Example
```rust
use hexga_bitflags::*;
#[bit_index]
#[repr(u8)]
enum Color
{
Red,
Green,
Blue = 5,
Yellow, // = 6
RedAndBlue = Color::Red | Self::Blue, // only defined in ColorFlags
Purple, // 7
GreenAndYellowAndPurple = ((Color::Yellow | Self::Purple)) | Self::Green, // only defined in ColorFlags
}
fn main()
{
let mut flags = Color::Red | Color::Blue;
assert_eq!(flags, ColorFlags::RedAndBlue);
assert_eq!(flags, ColorFlags::Red | ColorFlags::Blue);
assert!(flags.contains(Color::Red));
for color in ColorFlags::GreenAndYellowAndPurple
{
println!("{:?}", color);
}
flags.remove(Color::Red);
let blue = Color::try_from(flags).unwrap();
}
```
The generated code behind `#[bit_index]` will look like:
```rust
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] // The derive are also generated by `#[bit_index]`
pub enum Color {
Red = 0,
Green = 1,
Blue = 5,
Yellow = 6,
Purple = 7,
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ColorFlags
{
#[doc(hidden)]
_bits_do_not_use_it: u8,
}
impl ColorFlags
{
pub const Red : Self = Self {
_bits_do_not_use_it: 1 << (Color::Red as u8),
};
pub const Green : Self = ...;
pub const Blue : Self = ...;
pub const Yellow: Self = ...;
pub const RedAndBlue: Self = Self {
_bits_do_not_use_it: (Color::Red.bits() | Self::Blue.bits()),
};
pub const Purple: Self = ...;
pub const GreenAndYellowAndPurple: Self = Self {
_bits_do_not_use_it: ((Color::Yellow.bits() | Self::Purple.bits()) | Self::Green.bits()),
};
}
```
\+ some other methods and trait implementations.
## Inspiration & Motivation
This crate was mainly inspired by
- [enumflags2](https://crates.io/crates/enumflags2) while also wanting a way to defined all the constant and constant combination inside the flags structure.
- Also check [bitflags](https://crates.io/crates/bitflags) if you are looking for a popular crate for defining bitflags (without enum).