use std::cmp::Ordering; use std::hash::Hash; use superbitty::{bitfields, BitFieldCompatible}; #[derive(BitFieldCompatible, Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] enum EnumA { #[default] A, B, } #[derive(BitFieldCompatible, Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum EnumB { A, B, #[default] C, } bitfields! { #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Bitfields : u8 { enum_a: EnumA, pub enum_b: EnumB, } construct = fn new(); } #[test] fn new_and_set() { let mut instance = Bitfields::new(EnumA::B, EnumB::A); assert_eq!(instance.enum_a(), EnumA::B); assert_eq!(instance.enum_b(), EnumB::A); instance.set_enum_b(EnumB::C); assert_eq!(instance.enum_a(), EnumA::B); assert_eq!(instance.enum_b(), EnumB::C); instance.set_enum_a(EnumA::A); assert_eq!(instance.enum_a(), EnumA::A); assert_eq!(instance.enum_b(), EnumB::C); } #[test] fn default() { let instance = Bitfields::default(); assert_eq!(instance.enum_a(), EnumA::default()); assert_eq!(instance.enum_b(), EnumB::default()); } #[test] fn debug() { let debug_str = format!("{:?}", Bitfields::new(EnumA::B, EnumB::B)); assert_eq!(debug_str, "Bitfields { enum_a: B, enum_b: B }"); } #[test] fn clone_copy() { let original = Bitfields::new(EnumA::A, EnumB::C); let clone = original.clone(); assert_eq!(original.enum_a(), clone.enum_a()); assert_eq!(original.enum_b(), clone.enum_b()); let copy = original; assert_eq!(original.enum_a(), copy.enum_a()); assert_eq!(original.enum_b(), copy.enum_b()); } #[test] fn equality() { fn assert_eq() {} assert_eq::(); for a1 in [EnumA::A, EnumA::B] { for b1 in [EnumB::A, EnumB::B, EnumB::C] { for a2 in [EnumA::A, EnumA::B] { for b2 in [EnumB::A, EnumB::B, EnumB::C] { let one = Bitfields::new(a1, b1); let two = Bitfields::new(a2, b2); assert_eq!(one == two, a1 == a2 && b1 == b2); } } } } } #[test] fn comparison() { for a1 in [EnumA::A, EnumA::B] { for b1 in [EnumB::A, EnumB::B, EnumB::C] { for a2 in [EnumA::A, EnumA::B] { for b2 in [EnumB::A, EnumB::B, EnumB::C] { let one = Bitfields::new(a1, b1); let two = Bitfields::new(a2, b2); assert_eq!(one.cmp(&two), a1.cmp(&a2).then(b1.cmp(&b2))); assert_eq!(one.partial_cmp(&two), Some(a1.cmp(&a2).then(b1.cmp(&b2)))); } } } } } #[test] fn hash() { for a in [EnumA::A, EnumA::B] { for b in [EnumB::A, EnumB::B, EnumB::C] { let bitfields = Bitfields::new(a, b); #[derive(Debug, Default, PartialEq, Eq)] struct VecHasher(Vec); impl std::hash::Hasher for VecHasher { fn finish(&self) -> u64 { 0 } fn write(&mut self, bytes: &[u8]) { self.0.extend_from_slice(bytes); } } let mut bitfields_hasher = VecHasher::default(); bitfields.hash(&mut bitfields_hasher); let mut individual_hasher = VecHasher::default(); a.hash(&mut individual_hasher); b.hash(&mut individual_hasher); assert_eq!(bitfields_hasher, individual_hasher); } } } bitfields! { #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct Empty : u32 {} } #[test] fn empty() { _ = Empty::new().clone(); _ = Empty::default(); assert_eq!(Empty::default(), Empty::new()); assert!(!(Empty::default() != Empty::new())); assert!(Empty::default() >= Empty::new()); assert_eq!(Empty::new().partial_cmp(&Empty::new()), Some(Ordering::Equal)); }