1use std::{
2 cmp::Ordering,
3 fmt::Display,
4 ops::{BitAnd, BitOr, BitXor, Not},
5};
6
7use serde::{Deserialize, Serialize};
8
9use crate::misc::Join;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub enum ThreeValued {
14 False,
16 True,
18 Unknown,
20}
21
22impl PartialOrd for ThreeValued {
23 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
24 Some(self.cmp(other))
25 }
26}
27
28impl Ord for ThreeValued {
29 fn cmp(&self, other: &Self) -> Ordering {
30 match (self, other) {
31 (ThreeValued::False, ThreeValued::False) => Ordering::Equal,
32 (ThreeValued::False, ThreeValued::Unknown) => Ordering::Less,
33 (ThreeValued::False, ThreeValued::True) => Ordering::Less,
34
35 (ThreeValued::Unknown, ThreeValued::False) => Ordering::Greater,
36 (ThreeValued::Unknown, ThreeValued::Unknown) => Ordering::Equal,
37 (ThreeValued::Unknown, ThreeValued::True) => Ordering::Less,
38
39 (ThreeValued::True, ThreeValued::False) => Ordering::Greater,
40 (ThreeValued::True, ThreeValued::Unknown) => Ordering::Greater,
41 (ThreeValued::True, ThreeValued::True) => Ordering::Equal,
42 }
43 }
44}
45
46impl ThreeValued {
47 pub fn is_unknown(&self) -> bool {
49 matches!(self, ThreeValued::Unknown)
50 }
51
52 pub fn is_known(&self) -> bool {
54 !self.is_unknown()
55 }
56
57 pub fn is_false(&self) -> bool {
59 matches!(self, ThreeValued::False)
60 }
61
62 pub fn is_true(&self) -> bool {
64 matches!(self, ThreeValued::True)
65 }
66
67 pub fn from_bool(value: bool) -> ThreeValued {
68 if value {
69 ThreeValued::True
70 } else {
71 ThreeValued::False
72 }
73 }
74}
75
76impl Not for ThreeValued {
77 type Output = Self;
78
79 fn not(self) -> Self {
80 match self {
81 ThreeValued::False => ThreeValued::True,
82 ThreeValued::True => ThreeValued::False,
83 ThreeValued::Unknown => ThreeValued::Unknown,
84 }
85 }
86}
87
88impl BitAnd for ThreeValued {
89 type Output = Self;
90
91 fn bitand(self, rhs: Self) -> Self::Output {
92 match (self, rhs) {
93 (ThreeValued::False, _) => ThreeValued::False,
94 (_, ThreeValued::False) => ThreeValued::False,
95 (ThreeValued::Unknown, _) => ThreeValued::Unknown,
96 (_, ThreeValued::Unknown) => ThreeValued::Unknown,
97 (ThreeValued::True, ThreeValued::True) => ThreeValued::True,
98 }
99 }
100}
101
102impl BitOr for ThreeValued {
103 type Output = Self;
104
105 fn bitor(self, rhs: Self) -> Self::Output {
106 match (self, rhs) {
107 (ThreeValued::True, _) => ThreeValued::True,
108 (_, ThreeValued::True) => ThreeValued::True,
109 (ThreeValued::Unknown, _) => ThreeValued::Unknown,
110 (_, ThreeValued::Unknown) => ThreeValued::Unknown,
111 (ThreeValued::False, ThreeValued::False) => ThreeValued::False,
112 }
113 }
114}
115
116impl BitXor for ThreeValued {
117 type Output = Self;
118
119 fn bitxor(self, rhs: Self) -> Self::Output {
120 match (self, rhs) {
121 (ThreeValued::True, ThreeValued::True) | (ThreeValued::False, ThreeValued::False) => {
122 ThreeValued::False
123 }
124 (ThreeValued::True, ThreeValued::False) | (ThreeValued::False, ThreeValued::True) => {
125 ThreeValued::True
126 }
127 _ => ThreeValued::Unknown,
128 }
129 }
130}
131
132impl Join for ThreeValued {
133 fn join(self, rhs: &Self) -> Self {
134 match (self, rhs) {
135 (ThreeValued::False, ThreeValued::False) => ThreeValued::False,
136 (ThreeValued::True, ThreeValued::True) => ThreeValued::True,
137 (ThreeValued::False, ThreeValued::True) | (ThreeValued::True, ThreeValued::False) => {
138 ThreeValued::Unknown
139 }
140 (ThreeValued::Unknown, _) | (_, ThreeValued::Unknown) => ThreeValued::Unknown,
141 }
142 }
143}
144
145impl Display for ThreeValued {
146 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
147 let str = match self {
148 ThreeValued::False => "false",
149 ThreeValued::True => "true",
150 ThreeValued::Unknown => "unknown",
151 };
152 write!(f, "{}", str)
153 }
154}