Skip to content

Commit

Permalink
added optional derives for generated struct
Browse files Browse the repository at this point in the history
  • Loading branch information
TRI99ERED committed Feb 11, 2024
1 parent 61afdda commit 03a6923
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 48 deletions.
58 changes: 31 additions & 27 deletions tests/varflags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use varflags::varflags;

// Required attributes (added manually by user).
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[varflags]
enum TestInput {
#[varflags(Clone, Copy, Hash)]
enum TestInput2 {
// Representation of the unspecified bits will be calculated
A,
B,
Expand All @@ -31,48 +31,52 @@ enum TestInput {
fn example() -> Result<(), Box<dyn Error>> {
use bitworks::prelude::*;

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

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

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

assert!(c.contains(&TestInput::A));
assert!(!c.contains(&TestInput::H));
assert!(c.contains(&TestInput2::A));
assert!(!c.contains(&TestInput2::H));

let d = TestInput::A | TestInput::B;
let e = TestInput::A | TestInput::C;
let d = TestInput2::A | TestInput2::B;
let e = TestInput2::A | TestInput2::C;

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

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

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

let x = TestInputVarflags::all();
let x = TestInput2Varflags::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(), Some(TestInput2::A));
assert_eq!(iter.next(), Some(TestInput2::B));
assert_eq!(iter.next(), Some(TestInput2::C));
assert_eq!(iter.next(), Some(TestInput2::G));
assert_eq!(iter.next(), Some(TestInput2::D));
assert_eq!(iter.next(), Some(TestInput2::H));
assert_eq!(iter.next(), Some(TestInput2::F));
assert_eq!(iter.next(), Some(TestInput2::E));
assert_eq!(iter.next(), None);

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

println!("{c}");

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

Ok(())
}
89 changes: 80 additions & 9 deletions tests/varflags_spec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::error::Error;

// Specs for Bitflags attribute
// Specs for Varflags attribute

#[rustfmt::skip]

Expand Down Expand Up @@ -42,10 +42,10 @@ mod test_input_varflags {
// Pick appropriate Bitfield and generate Repr depending on the choice.
use bitworks::prelude::Bitset8 as Inner;
type Repr = u8;

// Use the enum.
use super::TestInput as E;

// Generated based on number of variants
const VAR_COUNT: usize = 8;

Expand Down Expand Up @@ -98,14 +98,37 @@ mod test_input_varflags {
0b01000000 => Ok(E::F),
0b00001000 => Ok(E::G),
0b00100000 => Ok(E::H),
_ => Err(ConvError::new(ConvTarget::Index(Inner::BYTE_SIZE), ConvTarget::Enum(VAR_COUNT))),
_ => Err(ConvError::new(
ConvTarget::Index(Inner::BYTE_SIZE),
ConvTarget::Enum(VAR_COUNT),
)),
}
}
}

// This struct will be generated with Bitflags appended to enum's name.
// Generate Display for input
impl core::fmt::Display for E {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match *self {
E::A => "A",
E::B => "B",
E::C => "C",
E::D => "D",
E::E => "E",
E::F => "F",
E::G => "G",
E::H => "H",
}
)
}
}

// This struct will be generated with Varflags appended to enum's name.
// Should derive Debug, PartialEq and Eq.
#[derive(Debug, PartialEq, Eq)]
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct TestInputVarflags(
// Attribute should calculate, that Inner is to be used here.
// Can't use ByteField here. Should be private.
Expand Down Expand Up @@ -247,12 +270,52 @@ mod test_input_varflags {
}
}

// Generate implementation of FromIterator for Bitflags
// Generate implementation of FromIterator for Varflags
impl FromIterator<E> for TestInputVarflags {
fn from_iter<T: IntoIterator<Item = E>>(iter: T) -> Self {
iter.into_iter().fold(Self::none(), |acc, v| acc | v)
}
}

// Generate Debug for Varflags
impl core::fmt::Debug for TestInputVarflags {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let count = self.variants().count();
write!(
f,
"TestInputVarflags{{{}}}",
self.variants()
.enumerate()
.fold("".to_owned(), |mut acc, (i, v)| {
acc.push_str(&v.to_string());
if i != count - 1 {
acc.push_str(", ")
}
acc
})
)
}
}

// Generate Display for Varflags
impl core::fmt::Display for TestInputVarflags {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let count = self.variants().count();
write!(
f,
"{{{}}}",
self.variants()
.enumerate()
.fold("".to_owned(), |mut acc, (i, v)| {
acc.push_str(&v.to_string());
if i != count - 1 {
acc.push_str(", ")
}
acc
})
)
}
}
}
// Reexport the struct locally.
use test_input_varflags::TestInputVarflags;
Expand All @@ -264,8 +327,12 @@ fn example() -> Result<(), Box<dyn Error>> {
let a = TestInput::A;
let b = TestInput::B;

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

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

assert!(c.contains(&TestInput::A));
Expand Down Expand Up @@ -297,8 +364,12 @@ fn example() -> Result<(), Box<dyn Error>> {

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

println!("{c}");

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

Ok(())
}
Loading

0 comments on commit 03a6923

Please sign in to comment.