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 match val {
15 -1 => Trit::Reject,
16 0 => Trit::Tend,
17 1 => Trit::Affirm,
18 _ => panic!("Invalid trit value: {}", val),
19 }
20 }
21}
22
23impl fmt::Display for Trit {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 match self {
26 Trit::Reject => write!(f, "reject"),
27 Trit::Tend => write!(f, "tend"),
28 Trit::Affirm => write!(f, "affirm"),
29 }
30 }
31}
32
33impl Neg for Trit {
34 type Output = Self;
35
36 fn neg(self) -> Self::Output {
37 match self {
38 Trit::Reject => Trit::Affirm,
39 Trit::Tend => Trit::Tend,
40 Trit::Affirm => Trit::Reject,
41 }
42 }
43}
44
45impl Add for Trit {
46 type Output = (Self, Self); fn add(self, rhs: Self) -> Self::Output {
49 match (self, rhs) {
50 (Trit::Reject, Trit::Reject) => (Trit::Affirm, Trit::Reject),
51 (Trit::Reject, Trit::Tend) => (Trit::Reject, Trit::Tend),
52 (Trit::Reject, Trit::Affirm) => (Trit::Tend, Trit::Tend),
53 (Trit::Tend, Trit::Reject) => (Trit::Reject, Trit::Tend),
54 (Trit::Tend, Trit::Tend) => (Trit::Tend, Trit::Tend),
55 (Trit::Tend, Trit::Affirm) => (Trit::Affirm, Trit::Tend),
56 (Trit::Affirm, Trit::Reject) => (Trit::Tend, Trit::Tend),
57 (Trit::Affirm, Trit::Tend) => (Trit::Affirm, Trit::Tend),
58 (Trit::Affirm, Trit::Affirm) => (Trit::Reject, Trit::Affirm),
59 }
60 }
61}
62
63impl Mul for Trit {
64 type Output = Self;
65
66 fn mul(self, rhs: Self) -> Self::Output {
67 match (self, rhs) {
68 (Trit::Tend, _) | (_, Trit::Tend) => Trit::Tend,
69 (Trit::Affirm, Trit::Affirm) | (Trit::Reject, Trit::Reject) => Trit::Affirm,
70 (Trit::Affirm, Trit::Reject) | (Trit::Reject, Trit::Affirm) => Trit::Reject,
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_negation() {
81 assert_eq!(-Trit::Reject, Trit::Affirm);
82 assert_eq!(-Trit::Tend, Trit::Tend);
83 assert_eq!(-Trit::Affirm, Trit::Reject);
84 }
85
86 #[test]
87 fn test_addition() {
88 assert_eq!(Trit::Reject + Trit::Reject, (Trit::Affirm, Trit::Reject));
89 assert_eq!(Trit::Reject + Trit::Tend, (Trit::Reject, Trit::Tend));
90 assert_eq!(Trit::Reject + Trit::Affirm, (Trit::Tend, Trit::Tend));
91 assert_eq!(Trit::Tend + Trit::Reject, (Trit::Reject, Trit::Tend));
92 assert_eq!(Trit::Tend + Trit::Tend, (Trit::Tend, Trit::Tend));
93 assert_eq!(Trit::Tend + Trit::Affirm, (Trit::Affirm, Trit::Tend));
94 assert_eq!(Trit::Affirm + Trit::Reject, (Trit::Tend, Trit::Tend));
95 assert_eq!(Trit::Affirm + Trit::Tend, (Trit::Affirm, Trit::Tend));
96 assert_eq!(Trit::Affirm + Trit::Affirm, (Trit::Reject, Trit::Affirm));
97 }
98
99 #[test]
100 fn test_multiplication() {
101 assert_eq!(Trit::Reject * Trit::Reject, Trit::Affirm);
102 assert_eq!(Trit::Reject * Trit::Tend, Trit::Tend);
103 assert_eq!(Trit::Reject * Trit::Affirm, Trit::Reject);
104 assert_eq!(Trit::Tend * Trit::Reject, Trit::Tend);
105 assert_eq!(Trit::Tend * Trit::Tend, Trit::Tend);
106 assert_eq!(Trit::Tend * Trit::Affirm, Trit::Tend);
107 assert_eq!(Trit::Affirm * Trit::Reject, Trit::Reject);
108 assert_eq!(Trit::Affirm * Trit::Tend, Trit::Tend);
109 assert_eq!(Trit::Affirm * Trit::Affirm, Trit::Affirm);
110 }
111}