1use std::fmt;
5use std::ops::{Add, AddAssign, Mul};
6
7use crate::NonZero;
8
9#[derive(Eq, PartialEq, Copy, Clone, Debug)]
17#[allow(missing_docs)]
18pub enum Binary {
19 Zero,
20 One,
21}
22
23impl NonZero for Binary {
24 fn is_not_zero(&self) -> bool {
25 match self {
26 Binary::Zero => false,
27 Binary::One => true,
28 }
29 }
30}
31
32impl num_traits::Zero for Binary {
33 fn zero() -> Self {
34 Self::Zero
35 }
36
37 fn is_zero(&self) -> bool {
38 self == &Binary::Zero
39 }
40}
41
42impl num_traits::One for Binary {
43 fn one() -> Self {
44 Self::One
45 }
46}
47
48impl Default for Binary {
49 fn default() -> Self {
50 Self::Zero
51 }
52}
53
54impl fmt::Display for Binary {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 f.write_str(match self {
57 Binary::Zero => "0",
58 Binary::One => "1",
59 })
60 }
61}
62
63impl Add<Binary> for Binary {
64 type Output = Self;
65
66 fn add(self, rhs: Binary) -> Self::Output {
67 match (self, rhs) {
68 (Binary::Zero, Binary::Zero) => Binary::Zero,
69 (Binary::Zero, Binary::One) => Binary::One,
70 (Binary::One, Binary::Zero) => Binary::One,
71 (Binary::One, Binary::One) => Binary::Zero,
72 }
73 }
74}
75
76impl Mul<Binary> for Binary {
77 type Output = Self;
78
79 fn mul(self, rhs: Binary) -> Self::Output {
80 match (self, rhs) {
81 (Binary::One, Binary::One) => Binary::One,
82 _ => Binary::Zero,
83 }
84 }
85}
86
87macro_rules! define_ops {
88 ($primitive:ident) => {
89 impl From<Binary> for $primitive {
90 fn from(other: Binary) -> Self {
91 From::from(&other)
92 }
93 }
94
95 impl From<&Binary> for $primitive {
96 fn from(other: &Binary) -> Self {
97 match other {
98 Binary::Zero => 0,
99 Binary::One => 1,
100 }
101 }
102 }
103
104 impl Add<Binary> for $primitive {
105 type Output = Self;
106
107 fn add(self, rhs: Binary) -> Self::Output {
108 Add::add(self, &rhs)
109 }
110 }
111
112 impl Add<&Binary> for $primitive {
113 type Output = Self;
114
115 fn add(self, rhs: &Binary) -> Self::Output {
116 match rhs {
117 Binary::Zero => self,
118 Binary::One => self + 1,
119 }
120 }
121 }
122
123 impl AddAssign<&Binary> for $primitive {
124 fn add_assign(&mut self, rhs: &Binary) {
125 match rhs {
126 Binary::Zero => {},
127 Binary::One => *self += 1,
128 }
129 }
130 }
131
132 impl Mul<Binary> for $primitive {
133 type Output = Self;
134
135 fn mul(self, rhs: Binary) -> Self::Output {
136 Mul::mul(self, &rhs)
137 }
138 }
139
140 impl Mul<&Binary> for $primitive {
141 type Output = Self;
142
143 fn mul(self, rhs: &Binary) -> Self::Output {
144 match rhs {
145 Binary::Zero => 0,
146 Binary::One => self,
147 }
148 }
149 }
150
151 impl Mul<&Binary> for &$primitive {
152 type Output = $primitive;
153
154 fn mul(self, rhs: &Binary) -> Self::Output {
155 match rhs {
156 Binary::Zero => 0,
157 Binary::One => *self,
158 }
159 }
160 }
161 }
162}
163
164define_ops!(i8);
165define_ops!(i16);
166define_ops!(i32);
167define_ops!(i64);
168define_ops!(i128);
169define_ops!(u8);
170define_ops!(u16);
171define_ops!(u32);
172define_ops!(u64);
173define_ops!(u128);
174
175#[cfg(test)]
176mod test {
177 use crate::Binary;
178
179 #[test]
180 fn test_integer() {
181 assert_eq!(1 + Binary::One, 2);
182 assert_eq!(-1 + Binary::One, 0);
183 assert_eq!(894 * Binary::One, 894);
184 assert_eq!(-894 * &Binary::One, -894);
185 assert_eq!(0_u8 * &Binary::One, 0);
186
187 assert_eq!(1 + Binary::Zero, 1);
188 assert_eq!(-1 + Binary::Zero, -1);
189 assert_eq!(894 * Binary::Zero, 0);
190 assert_eq!(-894 * &Binary::Zero, 0);
191 assert_eq!(0_u8 * &Binary::Zero, 0);
192 }
193}