1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum Tribool {
3 True,
4 False,
5 Null,
6}
7
8impl Tribool {
9 pub fn is_true(self) -> bool {
10 matches!(self, Self::True)
11 }
12
13 pub fn is_false(self) -> bool {
14 matches!(self, Self::False)
15 }
16
17 pub fn is_null(self) -> bool {
18 matches!(self, Self::Null)
19 }
20}
21
22impl std::ops::Not for Tribool {
23 type Output = Self;
24
25 fn not(self) -> Self::Output {
26 match self {
27 Self::True => Self::False,
28 Self::False => Self::True,
29 Self::Null => Self::Null,
30 }
31 }
32}
33
34impl From<bool> for Tribool {
35 fn from(v: bool) -> Self {
36 if v { Self::True } else { Self::False }
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn test_tribool() {
46 let t = Tribool::True;
47 let f = Tribool::False;
48 let n = Tribool::Null;
49
50 assert!(t.is_true());
51 assert!(!t.is_false());
52 assert!(!t.is_null());
53
54 assert!(!f.is_true());
55 assert!(f.is_false());
56 assert!(!f.is_null());
57
58 assert!(!n.is_true());
59 assert!(!n.is_false());
60 assert!(n.is_null());
61 }
62
63 #[test]
64 fn test_conversion_from_bool() {
65 assert_eq!(Tribool::from(true), Tribool::True);
66 assert_eq!(Tribool::from(false), Tribool::False);
67 }
68
69 #[test]
70 fn test_not_operator() {
71 assert_eq!(!Tribool::True, Tribool::False);
72 assert_eq!(!Tribool::False, Tribool::True);
73 assert_eq!(!Tribool::Null, Tribool::Null);
74 }
75}