use skleene::SKleene::*;
use core::ops::*;
use core::fmt;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum SKleene
{
False = 0,
True = 1,
Unknown = 2
}
const NOT_TABLE: [SKleene; 3] =
[True, False, Unknown];
const AND_TABLE: [[SKleene; 3]; 3] =
[[ False, False, False ],
[ False, True, Unknown],
[ False, Unknown, Unknown]
];
const OR_TABLE: [[SKleene; 3]; 3] =
[[ False, True, Unknown ],
[ True, True, True],
[ Unknown, True, Unknown]
];
impl SKleene
{
pub fn and(self, rhs: SKleene)-> SKleene {
AND_TABLE[self as usize][rhs as usize]
}
pub fn or(self, rhs: SKleene) -> SKleene {
OR_TABLE[self as usize][rhs as usize]
}
pub fn from_bool(b: bool) -> SKleene {
NOT_TABLE[(!b) as usize]
}
}
impl Not for SKleene
{
type Output = SKleene;
fn not(self) -> SKleene {
NOT_TABLE[self as usize]
}
}
impl BitAnd for SKleene
{
type Output = Self;
fn bitand(self, rhs: Self) -> Self {
self.and(rhs)
}
}
impl BitOr for SKleene
{
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
self.or(rhs)
}
}
impl fmt::Display for SKleene
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
False => write!(f, "false"),
True => write!(f, "true"),
Unknown => write!(f, "unknown"),
}
}
}
#[test]
fn test_not() {
assert_eq!(!True, False);
assert_eq!(!False, True);
assert_eq!(!Unknown, Unknown);
}
#[test]
fn test_and() {
let f = |a: SKleene, b, e| {
assert_eq!(a.and(b), e);
assert_eq!(b.and(a), e);
assert_eq!(a & b, e);
};
f(True, True, True);
f(True, False, False);
f(True, Unknown, Unknown);
f(False, False, False);
f(False, Unknown, False);
f(Unknown, Unknown, Unknown);
}
#[test]
fn test_or() {
let f = |a: SKleene, b, e| {
assert_eq!(a.or(b), e);
assert_eq!(b.or(a), e);
assert_eq!(a | b, e);
};
f(True, True, True);
f(True, False, True);
f(True, Unknown, True);
f(False, False, False);
f(False, Unknown, Unknown);
f(Unknown, Unknown, Unknown);
}
#[test]
fn test_from_bool() {
assert_eq!(SKleene::from_bool(true), True);
assert_eq!(SKleene::from_bool(false), False);
}