1use serde::Deserialize;
2use serde::Serialize;
3use strum::Display;
4
5#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord, Display)]
6#[repr(i8)]
7pub enum Trinary {
8 True = 1,
9 Maybe = 0,
10 False = -1,
11}
12
13impl Trinary {
14 #[inline(always)]
15 pub fn is_true(self) -> bool {
16 self == Trinary::True
17 }
18
19 #[inline(always)]
20 pub fn maybe_true(self) -> bool {
21 self == Trinary::True || self == Trinary::Maybe
22 }
23
24 #[inline(always)]
25 pub fn is_false(self) -> bool {
26 self == Trinary::False
27 }
28
29 #[inline(always)]
30 pub fn maybe_false(self) -> bool {
31 self == Trinary::False || self == Trinary::Maybe
32 }
33
34 #[inline(always)]
35 pub fn is_maybe(self) -> bool {
36 self == Trinary::Maybe
37 }
38
39 #[inline(always)]
40 pub fn and(self, other: Trinary) -> Trinary {
41 self & other
42 }
43
44 #[inline(always)]
45 pub fn or(self, other: Trinary) -> Trinary {
46 self | other
47 }
48
49 #[inline(always)]
50 pub fn xor(self, other: Trinary) -> Trinary {
51 self ^ other
52 }
53
54 #[inline(always)]
55 pub fn negate(self) -> Trinary {
56 !self
57 }
58}
59
60impl From<bool> for Trinary {
61 fn from(value: bool) -> Self {
62 if value { Trinary::True } else { Trinary::False }
63 }
64}
65
66impl From<Option<bool>> for Trinary {
67 fn from(value: Option<bool>) -> Self {
68 match value {
69 Some(value) => value.into(),
70 None => Trinary::Maybe,
71 }
72 }
73}
74
75impl From<Option<Trinary>> for Trinary {
76 fn from(value: Option<Trinary>) -> Self {
77 value.unwrap_or(Trinary::Maybe)
78 }
79}
80
81impl FromIterator<Trinary> for Trinary {
82 fn from_iter<I: IntoIterator<Item = Trinary>>(iter: I) -> Self {
83 let mut result = Trinary::True;
84 for value in iter {
85 result &= value;
86 }
87
88 result
89 }
90}
91
92impl TryInto<bool> for Trinary {
93 type Error = ();
94
95 fn try_into(self) -> Result<bool, Self::Error> {
96 match self {
97 Trinary::True => Ok(true),
98 Trinary::False => Ok(false),
99 Trinary::Maybe => Err(()),
100 }
101 }
102}
103
104impl core::ops::Not for Trinary {
105 type Output = Trinary;
106
107 fn not(self) -> Self::Output {
108 match self {
109 Trinary::True => Trinary::False,
110 Trinary::False => Trinary::True,
111 Trinary::Maybe => Trinary::Maybe,
112 }
113 }
114}
115
116impl core::ops::BitAnd for Trinary {
117 type Output = Trinary;
118
119 fn bitand(self, other: Self) -> Self::Output {
120 match (self, other) {
121 (Trinary::True, Trinary::True) => Trinary::True,
122 (Trinary::False, _) | (_, Trinary::False) => Trinary::False,
123 _ => Trinary::Maybe,
124 }
125 }
126}
127
128impl core::ops::BitOr for Trinary {
129 type Output = Trinary;
130
131 fn bitor(self, other: Self) -> Self::Output {
132 match (self, other) {
133 (Trinary::False, Trinary::False) => Trinary::False,
134 (Trinary::True, _) | (_, Trinary::True) => Trinary::True,
135 _ => Trinary::Maybe,
136 }
137 }
138}
139
140impl core::ops::BitXor for Trinary {
141 type Output = Trinary;
142
143 fn bitxor(self, other: Self) -> Self::Output {
144 match (self, other) {
145 (Trinary::True, Trinary::True) => Trinary::False,
146 (Trinary::False, Trinary::False) => Trinary::False,
147 _ => Trinary::Maybe,
148 }
149 }
150}
151
152impl core::ops::BitAndAssign for Trinary {
153 fn bitand_assign(&mut self, other: Self) {
154 *self = *self & other;
155 }
156}
157
158impl core::ops::BitOrAssign for Trinary {
159 fn bitor_assign(&mut self, other: Self) {
160 *self = *self | other;
161 }
162}
163
164impl core::ops::BitXorAssign for Trinary {
165 fn bitxor_assign(&mut self, other: Self) {
166 *self = *self ^ other;
167 }
168}
169
170impl core::ops::BitAnd<Option<bool>> for Trinary {
171 type Output = Trinary;
172
173 fn bitand(self, other: Option<bool>) -> Self::Output {
174 self & Trinary::from(other)
175 }
176}
177
178impl core::ops::BitOr<Option<bool>> for Trinary {
179 type Output = Trinary;
180
181 fn bitor(self, other: Option<bool>) -> Self::Output {
182 self | Trinary::from(other)
183 }
184}
185
186impl core::ops::BitXor<Option<bool>> for Trinary {
187 type Output = Trinary;
188
189 fn bitxor(self, other: Option<bool>) -> Self::Output {
190 self ^ Trinary::from(other)
191 }
192}
193
194impl core::ops::BitAnd<bool> for Trinary {
195 type Output = Trinary;
196
197 fn bitand(self, other: bool) -> Self::Output {
198 self & Trinary::from(other)
199 }
200}
201
202impl core::ops::BitOr<bool> for Trinary {
203 type Output = Trinary;
204
205 fn bitor(self, other: bool) -> Self::Output {
206 self | Trinary::from(other)
207 }
208}
209
210impl core::ops::BitXor<bool> for Trinary {
211 type Output = Trinary;
212
213 fn bitxor(self, other: bool) -> Self::Output {
214 self ^ Trinary::from(other)
215 }
216}
217
218impl core::ops::BitAndAssign<Option<bool>> for Trinary {
219 fn bitand_assign(&mut self, other: Option<bool>) {
220 *self = *self & other;
221 }
222}
223
224impl core::ops::BitOrAssign<Option<bool>> for Trinary {
225 fn bitor_assign(&mut self, other: Option<bool>) {
226 *self = *self | other;
227 }
228}
229
230impl core::ops::BitAndAssign<bool> for Trinary {
231 fn bitand_assign(&mut self, other: bool) {
232 *self = *self & other;
233 }
234}
235
236impl core::ops::BitOrAssign<bool> for Trinary {
237 fn bitor_assign(&mut self, other: bool) {
238 *self = *self | other;
239 }
240}