use std::{
fmt::{
self,
Display,
Formatter,
},
ops::{
BitAnd,
BitAndAssign,
BitOr,
BitOrAssign,
BitXor,
BitXorAssign,
Not,
},
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Bit {
Zero,
One,
}
impl Bit {
#[must_use]
pub const fn zero() -> Self {
Self::Zero
}
#[must_use]
pub const fn one() -> Self {
Self::One
}
pub fn flip(&mut self) {
*self = match self {
Self::Zero => Self::One,
Self::One => Self::Zero,
}
}
pub fn set(&mut self) {
*self = Self::One;
}
pub fn unset(&mut self) {
*self = Self::Zero;
}
#[must_use]
pub fn is_set(&self) -> bool {
*self == Self::One
}
#[must_use]
pub fn is_unset(&self) -> bool {
*self == Self::Zero
}
}
impl Display for Bit {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::Zero => write!(f, "0"),
Self::One => write!(f, "1"),
}
}
}
impl Default for Bit {
fn default() -> Self {
Self::zero()
}
}
impl From<u8> for Bit {
fn from(value: u8) -> Self {
match value {
0 => Self::Zero,
_ => Self::One,
}
}
}
impl From<Bit> for u8 {
fn from(bit: Bit) -> Self {
match bit {
Bit::Zero => 0,
Bit::One => 1,
}
}
}
impl Not for Bit {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Self::Zero => Self::One,
Self::One => Self::Zero,
}
}
}
impl BitOr for Bit {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
match (self, rhs) {
(Self::Zero, Self::Zero) => Self::Zero,
_ => Self::One,
}
}
}
impl BitOrAssign for Bit {
fn bitor_assign(&mut self, rhs: Self) {
*self = *self | rhs;
}
}
impl BitAnd for Bit {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
match (self, rhs) {
(Self::One, Self::One) => Self::One,
_ => Self::Zero,
}
}
}
impl BitAndAssign for Bit {
fn bitand_assign(&mut self, rhs: Self) {
*self = *self & rhs;
}
}
impl BitXor for Bit {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
match (self, rhs) {
(Self::Zero, Self::One) | (Self::One, Self::Zero) => Self::One,
_ => Self::Zero,
}
}
}
impl BitXorAssign for Bit {
fn bitxor_assign(&mut self, rhs: Self) {
*self = *self ^ rhs;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_zero() {
let bit = Bit::zero();
assert_eq!(bit, Bit::Zero);
assert_eq!(bit.to_string(), "0");
}
#[test]
fn test_one() {
let bit = Bit::one();
assert_eq!(bit, Bit::One);
assert_eq!(bit.to_string(), "1");
}
#[test]
fn test_flip_zero() {
let mut bit = Bit::zero();
bit.flip();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_flip_one() {
let mut bit = Bit::one();
bit.flip();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_set_zero() {
let mut bit = Bit::zero();
bit.set();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_set_one() {
let mut bit = Bit::one();
bit.set();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_unset_zero() {
let mut bit = Bit::zero();
bit.unset();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_unset_one() {
let mut bit = Bit::one();
bit.unset();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_to_u8_zero() {
let bit = Bit::zero();
assert_eq!(u8::from(bit), 0);
}
#[test]
fn test_to_u8_one() {
let bit = Bit::one();
assert_eq!(u8::from(bit), 1);
}
#[test]
fn test_display_zero() {
let bit = Bit::zero();
assert_eq!(format!("{}", bit), "0");
}
#[test]
fn test_display_one() {
let bit = Bit::one();
assert_eq!(format!("{}", bit), "1");
}
#[test]
fn test_default() {
let bit = Bit::default();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_not_zero() {
let bit = !Bit::zero();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_not_one() {
let bit = !Bit::one();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitor_zero_zero() {
let bit = Bit::zero() | Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitor_zero_one() {
let bit = Bit::zero() | Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitor_one_zero() {
let bit = Bit::one() | Bit::zero();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitor_one_one() {
let bit = Bit::one() | Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitorassign_zero_zero() {
let mut bit = Bit::zero();
bit |= Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitorassign_zero_one() {
let mut bit = Bit::zero();
bit |= Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitorassign_one_zero() {
let mut bit = Bit::one();
bit |= Bit::zero();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitorassign_one_one() {
let mut bit = Bit::one();
bit |= Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitand_zero_zero() {
let bit = Bit::zero() & Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitand_zero_one() {
let bit = Bit::zero() & Bit::one();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitand_one_zero() {
let bit = Bit::one() & Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitand_one_one() {
let bit = Bit::one() & Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitandassign_zero_zero() {
let mut bit = Bit::zero();
bit &= Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitandassign_zero_one() {
let mut bit = Bit::zero();
bit &= Bit::one();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitandassign_one_zero() {
let mut bit = Bit::one();
bit &= Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitandassign_one_one() {
let mut bit = Bit::one();
bit &= Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitxor_zero_zero() {
let bit = Bit::zero() ^ Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitxor_zero_one() {
let bit = Bit::zero() ^ Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitxor_one_zero() {
let bit = Bit::one() ^ Bit::zero();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitxor_one_one() {
let bit = Bit::one() ^ Bit::one();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitxorassign_zero_zero() {
let mut bit = Bit::zero();
bit ^= Bit::zero();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_bitxorassign_zero_one() {
let mut bit = Bit::zero();
bit ^= Bit::one();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitxorassign_one_zero() {
let mut bit = Bit::one();
bit ^= Bit::zero();
assert_eq!(bit, Bit::One);
}
#[test]
fn test_bitxorassign_one_one() {
let mut bit = Bit::one();
bit ^= Bit::one();
assert_eq!(bit, Bit::Zero);
}
#[test]
fn test_is_set_zero() {
let bit = Bit::zero();
assert!(!bit.is_set());
}
#[test]
fn test_is_set_one() {
let bit = Bit::one();
assert!(bit.is_set());
}
#[test]
fn test_is_unset_zero() {
let bit = Bit::zero();
assert!(bit.is_unset());
}
#[test]
fn test_is_unset_one() {
let bit = Bit::one();
assert!(!bit.is_unset());
}
#[test]
fn test_is_set_after_set() {
let mut bit = Bit::zero();
bit.set();
assert!(bit.is_set());
}
#[test]
fn test_is_unset_after_set() {
let mut bit = Bit::zero();
bit.set();
assert!(!bit.is_unset());
}
#[test]
fn test_is_set_after_unset() {
let mut bit = Bit::one();
bit.unset();
assert!(!bit.is_set());
}
#[test]
fn test_is_unset_after_unset() {
let mut bit = Bit::one();
bit.unset();
assert!(bit.is_unset());
}
}