logicrs 0.6.1

Rust library for logic expression
Documentation
use std::{
    fmt::{self, Debug, Display, Write},
    ops::{BitAnd, BitOr, Deref, DerefMut, Not},
};

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Lbool(pub u8);

impl Lbool {
    pub const FALSE: Lbool = Lbool(0);
    pub const TRUE: Lbool = Lbool(1);
    pub const NONE: Lbool = Lbool(2);

    #[inline]
    pub fn is_true(self) -> bool {
        self == Self::TRUE
    }

    #[inline]
    pub fn is_false(self) -> bool {
        self == Self::FALSE
    }

    #[inline]
    pub fn is_none(self) -> bool {
        self.0 & 2 != 0
    }

    #[inline]
    pub fn not_if(self, x: bool) -> Self {
        if x { !self } else { self }
    }
}

impl From<bool> for Lbool {
    #[inline]
    fn from(value: bool) -> Self {
        Self(value as u8)
    }
}

impl From<Lbool> for Option<bool> {
    #[inline]
    fn from(val: Lbool) -> Self {
        match val {
            Lbool::TRUE => Some(true),
            Lbool::FALSE => Some(false),
            _ => None,
        }
    }
}

impl Default for Lbool {
    #[inline]
    fn default() -> Self {
        Self::NONE
    }
}

impl Debug for Lbool {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let field = match *self {
            Lbool::TRUE => '1',
            Lbool::FALSE => '0',
            _ => 'X',
        };
        f.write_char(field)
    }
}

impl Display for Lbool {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{self:?}")
    }
}

impl Not for Lbool {
    type Output = Self;

    #[inline]
    fn not(self) -> Self::Output {
        Lbool(self.0 ^ 1)
    }
}

impl BitAnd for Lbool {
    type Output = Lbool;

    #[inline]
    fn bitand(self, rhs: Self) -> Self::Output {
        if self.is_none() {
            if rhs.is_false() {
                Self::FALSE
            } else {
                Self::NONE
            }
        } else if rhs.is_none() {
            if self.is_false() {
                Self::FALSE
            } else {
                Self::NONE
            }
        } else {
            Self(self.0 & rhs.0)
        }
    }
}

impl BitOr for Lbool {
    type Output = Lbool;

    #[inline]
    fn bitor(self, rhs: Self) -> Self::Output {
        if self.is_none() {
            if rhs.is_true() {
                Self::TRUE
            } else {
                Self::NONE
            }
        } else if rhs.is_none() {
            if self.is_true() {
                Self::TRUE
            } else {
                Self::NONE
            }
        } else {
            Self(self.0 | rhs.0)
        }
    }
}

#[derive(Clone, Default, PartialEq, Eq)]
pub struct LboolVec {
    v: Vec<Lbool>,
}

impl Deref for LboolVec {
    type Target = Vec<Lbool>;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.v
    }
}

impl DerefMut for LboolVec {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.v
    }
}

impl Debug for LboolVec {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for lb in self.v.iter().rev() {
            Debug::fmt(lb, f)?;
        }
        Ok(())
    }
}

impl Display for LboolVec {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{self:?}")
    }
}