mago_trinary/
lib.rs

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}