varflags 0.1.0

Crate exporting varflags macro, allowing to use unit-like enums in conjunction with Varflags struct to create easy to use bitflags data structure defined over enum variants.
Documentation
[![Rust](https://github.com/TRI99ERED/varflags/actions/workflows/rust.yml/badge.svg)](https://github.com/TRI99ERED/varflags/actions/workflows/rust.yml)

Crate exporting `varflags` macro, allowing to use unit-like enums in conjunction with `Varflags` struct to create easy to use bitflags data structure defined over enum variants.

Enable feature `"serde"` to enable `serde::Serialize` and `serde::Deserialize` for most applicable types.

Heavily inspired by the famous [enumflags2](https://crates.io/crates/enumflags2) crate. It's likely
better to use that crate, as it is well tested and adopted.
`varflags` was created as a hands-on learning experience for me at building procedural macros (contains no code from `enumflags2`). It's also depending on my other crate [bitworks](https://crates.io/crates/bitworks), which
is a generic bitset data structure implementation from scratch. Unless you use `bitworks`, there's little reason to use `varflags`.

## Examples

```rust
use varflags::varflags;
 
#[derive(Copy, PartialEq, Eq, Debug)]

#[varflags]

enum TestInput {
    // Representation of the unspecified bits will be calculated
    A,
    B,
    C,
    // Or you can manually specify:
    D = 0b00010000,
    // Subattributes allow to change representation too:
    #[flag = 0b10000000]
    E,
    // or like this (corresponds to 0b01000000):
    #[shift = 6]
    F,
    // Representation of the unspecified bits will be calculated
    G,
    H,
}
 
fn example() {
    // Input enum variants are still intact.
    let a = TestInput::A;
    let b = TestInput::B;
    
    // All variants have correctly set discriminants.
    assert_eq!(u8::from(TestInput::D), 0b00010000);
    assert_eq!(u8::from(TestInput::E), 0b10000000);
    assert_eq!(u8::from(TestInput::F), 0b01000000);
 
    // Operators allow easy construction of Varflags values.
    // Here c is Varflags<TestInput, Bitset8>.
    let c = a | b | TestInput::D;
    //                                                                             EFHDGCBA
    assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));
 
    // Can check if Varflags value contains a flag.
    assert!(c.contains(&TestInput::A));
    assert!(!c.contains(&TestInput::H));
 
    // Can check if Varflags value includes all flags of another Varflags value.
    let d = TestInput::A | TestInput::B;
    let e = TestInput::A | TestInput::C;
    
    assert!(c.includes(&d));
    assert!(!c.includes(&e));
 
 
    // Can check if two Varflags values share at least one flag between themselves.
    let f = TestInput::F | TestInput::H;
 
    assert!(c.intersects(&e));
    assert!(!c.intersects(&f));
 
    // Can iterate over contained flags.
    let x = TestInputVarflags::ALL;
    let mut iter = x.variants();
 
    assert_eq!(iter.next(), Some(TestInput::A));
    assert_eq!(iter.next(), Some(TestInput::B));
    assert_eq!(iter.next(), Some(TestInput::C));
    assert_eq!(iter.next(), Some(TestInput::G));
    assert_eq!(iter.next(), Some(TestInput::D));
    assert_eq!(iter.next(), Some(TestInput::H));
    assert_eq!(iter.next(), Some(TestInput::F));
    assert_eq!(iter.next(), Some(TestInput::E));
    assert_eq!(iter.next(), None);
 
    // Can collect from iterator over flags.
    let iter = c.variants();
    let c: TestInputVarflags = iter.collect();
    //                                                                             EFHDGCBA
    assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));
 
    // Can be made into string with Display or Debug.
    let display = format!("{c}");
    let debug = format!("{c:?}");

    assert_eq!(display.as_str(), "{A, B, D}");
    assert_eq!(debug.as_str(), "Varflags{A, B, D}");
}
```

## License


Licensed under either of

 * Apache License, Version 2.0
   ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license
   ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

## Contribution


Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.