use std::hash::Hash;
use crate::traits::LogicValue;
impl LogicValue for bool {
fn num_values() -> usize {
2
}
fn value(idx: usize) -> Self {
match idx {
0 => false,
1 => true,
_ => panic!("index out of bounds"),
}
}
fn zero() -> Self {
false
}
fn one() -> Self {
true
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub enum Bool {
L,
H,
}
impl LogicValue for Bool {
fn num_values() -> usize {
2
}
fn value(idx: usize) -> Self {
match idx {
0 => Self::L,
1 => Self::H,
_ => panic!("index out of bounds"),
}
}
fn zero() -> Self {
Self::L
}
fn one() -> Self {
Self::H
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
pub enum Logic3 {
L,
H,
#[default]
X,
}
impl From<bool> for Logic3 {
fn from(value: bool) -> Self {
match value {
true => Self::H,
false => Self::L,
}
}
}
impl From<Option<bool>> for Logic3 {
fn from(value: Option<bool>) -> Self {
match value {
None => Self::X,
Some(true) => Self::H,
Some(false) => Self::L,
}
}
}
impl TryInto<bool> for Logic3 {
type Error = ();
fn try_into(self) -> Result<bool, Self::Error> {
match self {
Logic3::L => Ok(false),
Logic3::H => Ok(true),
Logic3::X => Err(()),
}
}
}
impl LogicValue for Logic3 {
fn value(idx: usize) -> Self {
match idx {
0 => Self::L,
1 => Self::H,
2 => Self::X,
_ => panic!("index out of bounds"),
}
}
fn zero() -> Self {
Self::L
}
fn one() -> Self {
Self::H
}
fn num_values() -> usize {
3
}
}
impl std::ops::Not for Logic3 {
type Output = Self;
fn not(self) -> Self::Output {
use Logic3::*;
match self {
L => H,
H => L,
X => X,
}
}
}
impl std::ops::BitAnd for Logic3 {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
use Logic3::*;
match (self, rhs) {
(L, _) | (_, L) => L,
(H, H) => H,
_ => X,
}
}
}
impl std::ops::BitOr for Logic3 {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
use Logic3::*;
match (self, rhs) {
(H, _) | (_, H) => H,
(L, L) => L,
_ => X,
}
}
}
impl std::ops::BitXor for Logic3 {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
use Logic3::*;
match (self, rhs) {
(H, H) | (L, L) => L,
(H, L) | (L, H) => H,
(X, _) | (_, X) => X,
}
}
}
#[test]
fn test_logic3_ops() {
use Logic3::*;
assert_eq!(H & H, H);
assert_eq!(L & X, L);
assert_eq!(X & L, L);
assert_eq!(H & X, X);
assert_eq!(L | L, L);
assert_eq!(H | X, H);
assert_eq!(X | H, H);
assert_eq!(X | L, X);
}