logic_form/
lbool.rs

1use std::{
2    fmt::Debug,
3    ops::{BitAnd, BitOr, Not},
4};
5
6#[derive(Clone, Copy, PartialEq, Eq)]
7pub struct Lbool(pub u8);
8
9impl Lbool {
10    pub const FALSE: Lbool = Lbool(0);
11    pub const TRUE: Lbool = Lbool(1);
12    pub const NONE: Lbool = Lbool(2);
13
14    #[inline]
15    pub fn is_true(self) -> bool {
16        self == Self::TRUE
17    }
18
19    #[inline]
20    pub fn is_false(self) -> bool {
21        self == Self::FALSE
22    }
23
24    #[inline]
25    pub fn is_none(self) -> bool {
26        self.0 & 2 != 0
27    }
28
29    pub fn not_if(self, x: bool) -> Self {
30        if x { !self } else { self }
31    }
32}
33
34impl From<bool> for Lbool {
35    #[inline]
36    fn from(value: bool) -> Self {
37        Self(value as u8)
38    }
39}
40
41impl From<Lbool> for Option<bool> {
42    #[inline]
43    fn from(val: Lbool) -> Self {
44        match val {
45            Lbool::TRUE => Some(true),
46            Lbool::FALSE => Some(false),
47            _ => None,
48        }
49    }
50}
51
52impl Default for Lbool {
53    fn default() -> Self {
54        Self::NONE
55    }
56}
57
58impl Debug for Lbool {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        let field = match *self {
61            Lbool::TRUE => Some(true),
62            Lbool::FALSE => Some(false),
63            _ => None,
64        };
65        f.debug_tuple("Lbool").field(&field).finish()
66    }
67}
68
69impl Not for Lbool {
70    type Output = Self;
71
72    #[inline]
73    fn not(self) -> Self::Output {
74        Lbool(self.0 ^ 1)
75    }
76}
77
78impl BitAnd for Lbool {
79    type Output = Lbool;
80
81    fn bitand(self, rhs: Self) -> Self::Output {
82        if self.is_none() {
83            if rhs.is_false() {
84                Self::FALSE
85            } else {
86                Self::NONE
87            }
88        } else if rhs.is_none() {
89            if self.is_false() {
90                Self::FALSE
91            } else {
92                Self::NONE
93            }
94        } else {
95            Self(self.0 & rhs.0)
96        }
97    }
98}
99
100impl BitOr for Lbool {
101    type Output = Lbool;
102
103    fn bitor(self, rhs: Self) -> Self::Output {
104        if self.is_none() {
105            if rhs.is_true() {
106                Self::TRUE
107            } else {
108                Self::NONE
109            }
110        } else if rhs.is_none() {
111            if self.is_true() {
112                Self::TRUE
113            } else {
114                Self::NONE
115            }
116        } else {
117            Self(self.0 | rhs.0)
118        }
119    }
120}