1use std::fmt;
2use std::ops::{Add, Mul, Neg};
3use serde::{Serialize, Deserialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
6pub enum Trit {
7 Reject = -1, Tend = 0, Affirm = 1, }
11
12impl From<i8> for Trit {
13 fn from(val: i8) -> Self {
14 if val > 0 { Trit::Affirm }
19 else if val < 0 { Trit::Reject }
20 else { Trit::Tend }
21 }
22}
23
24impl fmt::Display for Trit {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 match self {
27 Trit::Reject => write!(f, "reject"),
28 Trit::Tend => write!(f, "tend"),
29 Trit::Affirm => write!(f, "affirm"),
30 }
31 }
32}
33
34impl Neg for Trit {
35 type Output = Self;
36
37 fn neg(self) -> Self::Output {
38 match self {
39 Trit::Reject => Trit::Affirm,
40 Trit::Tend => Trit::Tend,
41 Trit::Affirm => Trit::Reject,
42 }
43 }
44}
45
46impl Add for Trit {
47 type Output = (Self, Self); fn add(self, rhs: Self) -> Self::Output {
50 match (self, rhs) {
51 (Trit::Reject, Trit::Reject) => (Trit::Affirm, Trit::Reject),
52 (Trit::Reject, Trit::Tend) => (Trit::Reject, Trit::Tend),
53 (Trit::Reject, Trit::Affirm) => (Trit::Tend, Trit::Tend),
54 (Trit::Tend, Trit::Reject) => (Trit::Reject, Trit::Tend),
55 (Trit::Tend, Trit::Tend) => (Trit::Tend, Trit::Tend),
56 (Trit::Tend, Trit::Affirm) => (Trit::Affirm, Trit::Tend),
57 (Trit::Affirm, Trit::Reject) => (Trit::Tend, Trit::Tend),
58 (Trit::Affirm, Trit::Tend) => (Trit::Affirm, Trit::Tend),
59 (Trit::Affirm, Trit::Affirm) => (Trit::Reject, Trit::Affirm),
60 }
61 }
62}
63
64impl Mul for Trit {
65 type Output = Self;
66
67 fn mul(self, rhs: Self) -> Self::Output {
68 match (self, rhs) {
69 (Trit::Tend, _) | (_, Trit::Tend) => Trit::Tend,
70 (Trit::Affirm, Trit::Affirm) | (Trit::Reject, Trit::Reject) => Trit::Affirm,
71 (Trit::Affirm, Trit::Reject) | (Trit::Reject, Trit::Affirm) => Trit::Reject,
72 }
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_negation() {
82 assert_eq!(-Trit::Reject, Trit::Affirm);
83 assert_eq!(-Trit::Tend, Trit::Tend);
84 assert_eq!(-Trit::Affirm, Trit::Reject);
85 }
86
87 #[test]
88 fn test_addition() {
89 assert_eq!(Trit::Reject + Trit::Reject, (Trit::Affirm, Trit::Reject));
90 assert_eq!(Trit::Reject + Trit::Tend, (Trit::Reject, Trit::Tend));
91 assert_eq!(Trit::Reject + Trit::Affirm, (Trit::Tend, Trit::Tend));
92 assert_eq!(Trit::Tend + Trit::Reject, (Trit::Reject, Trit::Tend));
93 assert_eq!(Trit::Tend + Trit::Tend, (Trit::Tend, Trit::Tend));
94 assert_eq!(Trit::Tend + Trit::Affirm, (Trit::Affirm, Trit::Tend));
95 assert_eq!(Trit::Affirm + Trit::Reject, (Trit::Tend, Trit::Tend));
96 assert_eq!(Trit::Affirm + Trit::Tend, (Trit::Affirm, Trit::Tend));
97 assert_eq!(Trit::Affirm + Trit::Affirm, (Trit::Reject, Trit::Affirm));
98 }
99
100 #[test]
101 fn test_multiplication() {
102 assert_eq!(Trit::Reject * Trit::Reject, Trit::Affirm);
103 assert_eq!(Trit::Reject * Trit::Tend, Trit::Tend);
104 assert_eq!(Trit::Reject * Trit::Affirm, Trit::Reject);
105 assert_eq!(Trit::Tend * Trit::Reject, Trit::Tend);
106 assert_eq!(Trit::Tend * Trit::Tend, Trit::Tend);
107 assert_eq!(Trit::Tend * Trit::Affirm, Trit::Tend);
108 assert_eq!(Trit::Affirm * Trit::Reject, Trit::Reject);
109 assert_eq!(Trit::Affirm * Trit::Tend, Trit::Tend);
110 assert_eq!(Trit::Affirm * Trit::Affirm, Trit::Affirm);
111 }
112}