Skip to content

Commit

Permalink
finished readme for varflags
Browse files Browse the repository at this point in the history
  • Loading branch information
TRI99ERED committed Feb 15, 2024
1 parent db4f1ab commit 3399676
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 90 deletions.
115 changes: 68 additions & 47 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ Crate exporting `varflags` macro, allowing to use unit-like enums in conjunction

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 {
Expand All @@ -25,52 +30,68 @@ enum TestInput {
G,
H,
}

let a = TestInput::A;
let b = TestInput::B;

assert_eq!(u8::from(TestInput::D), 0b00010000);
assert_eq!(u8::from(TestInput::E), 0b10000000);
assert_eq!(u8::from(TestInput::F), 0b01000000);

let c = a | b | TestInput::D;
// EFHDGCBA
assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));

assert!(c.contains(&TestInput::A));
assert!(!c.contains(&TestInput::H));
let d = TestInput::A | TestInput::B;
let e = TestInput::A | TestInput::C;

assert!(c.includes(&d));
assert!(!c.includes(&e));

let f = TestInput::F | TestInput::H;

assert!(c.intersects(&e));
assert!(!c.intersects(&f));

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);

let iter = c.variants();
let c: TestInputVarflags = iter.collect();
// EFHDGCBA
assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));

println!("{c}");

println!("{c:?}");

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
Expand Down
79 changes: 39 additions & 40 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
//!
//! # Examples
//! ```rust
//! # use std::error::Error;
//! # fn main() -> Result<(), Box<dyn Error>> {
//! use varflags::varflags;
//!
//! #[derive(Copy, PartialEq, Eq, Debug)]
Expand All @@ -29,55 +27,56 @@
//! H,
//! }
//!
//! let a = TestInput::A;
//! let b = TestInput::B;
//! fn main() {
//! let a = TestInput::A;
//! let b = TestInput::B;
//!
//! assert_eq!(u8::from(TestInput::D), 0b00010000);
//! assert_eq!(u8::from(TestInput::E), 0b10000000);
//! assert_eq!(u8::from(TestInput::F), 0b01000000);
//! assert_eq!(u8::from(TestInput::D), 0b00010000);
//! assert_eq!(u8::from(TestInput::E), 0b10000000);
//! assert_eq!(u8::from(TestInput::F), 0b01000000);
//!
//! let c = a | b | TestInput::D;
//! // EFHDGCBA
//! assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));
//! let c = a | b | TestInput::D;
//! // EFHDGCBA
//! assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));
//!
//! assert!(c.contains(&TestInput::A));
//! assert!(!c.contains(&TestInput::H));
//! assert!(c.contains(&TestInput::A));
//! assert!(!c.contains(&TestInput::H));
//!
//! let d = TestInput::A | TestInput::B;
//! let e = TestInput::A | TestInput::C;
//! let d = TestInput::A | TestInput::B;
//! let e = TestInput::A | TestInput::C;
//!
//! assert!(c.includes(&d));
//! assert!(!c.includes(&e));
//! assert!(c.includes(&d));
//! assert!(!c.includes(&e));
//!
//! let f = TestInput::F | TestInput::H;
//! let f = TestInput::F | TestInput::H;
//!
//! assert!(c.intersects(&e));
//! assert!(!c.intersects(&f));
//! assert!(c.intersects(&e));
//! assert!(!c.intersects(&f));
//!
//! let x = TestInputVarflags::ALL;
//! let mut iter = x.variants();
//! 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);
//! 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);
//!
//! let iter = c.variants();
//! let c: TestInputVarflags = iter.collect();
//! // EFHDGCBA
//! assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));
//! let iter = c.variants();
//! let c: TestInputVarflags = iter.collect();
//! // EFHDGCBA
//! assert_eq!(c, TestInputVarflags::_from_inner(bitworks::prelude::Bitset8::new(0b00010011)));
//!
//! println!("{c}");
//! let display = format!("{c}");
//! let debug = format!("{c:?}");
//!
//! println!("{c:?}");
//!
//! # Ok(())
//! # }
//! assert_eq!(display.as_str(), "{A, B, D}");
//! assert_eq!(debug.as_str(), "Varflags{A, B, D}");
//! }
//! ```
extern crate varflags_attribute;
Expand Down Expand Up @@ -359,4 +358,4 @@ where
})
)
}
}
}
8 changes: 5 additions & 3 deletions tests/varflags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ fn example() -> Result<(), Box<dyn Error>> {
// EFHDGCBA
assert_eq!(c, TestInputVarflags::_from_inner(Bitset8::new(0b00010011)));

println!("{c}");

println!("{c:?}");
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}");

Ok(())
}

0 comments on commit 3399676

Please sign in to comment.