use std::ops::Mul;
#[allow(unused_imports)]
use crate::{Row, RowBuf, Stage};
#[repr(u8)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Parity {
Even = 0,
Odd = 1,
}
impl Parity {
#[inline(always)]
pub fn from_is_odd(v: bool) -> Self {
match v {
false => Parity::Even,
true => Parity::Odd,
}
}
#[inline(always)]
pub fn from_number(v: usize) -> Parity {
Self::from_is_odd(v % 2 != 0)
}
#[inline(always)]
pub fn zero_or_one(self) -> u8 {
match self {
Parity::Even => 0,
Parity::Odd => 1,
}
}
#[inline(always)]
pub fn plus_or_minus(self) -> char {
match self {
Parity::Even => '+',
Parity::Odd => '-',
}
}
}
impl Mul for Parity {
type Output = Self;
#[inline(always)]
fn mul(self, rhs: Self) -> Self::Output {
Self::from_is_odd(self != rhs)
}
}
#[cfg(test)]
mod tests {
use crate::{RowBuf, Stage};
use super::Parity::{Even, Odd};
use super::*;
#[test]
fn mul() {
assert_eq!(Even * Even, Even);
assert_eq!(Even * Odd, Odd);
assert_eq!(Odd * Even, Odd);
assert_eq!(Odd * Odd, Even);
}
#[test]
fn from_number() {
assert_eq!(Parity::from_number(0), Even);
assert_eq!(Parity::from_number(1000), Even);
assert_eq!(Parity::from_number(1), Odd);
assert_eq!(Parity::from_number(47), Odd);
}
#[test]
fn row_parity() {
assert_eq!(RowBuf::rounds(Stage::TWO).parity(), Even);
assert_eq!(RowBuf::rounds(Stage::MAJOR).parity(), Even);
assert_eq!(RowBuf::parse("13245").unwrap().parity(), Odd);
assert_eq!(RowBuf::parse("231546").unwrap().parity(), Odd);
assert_eq!(RowBuf::parse("231564").unwrap().parity(), Even);
}
}