1use std::cmp::Ordering;
2
3use super::{
4 float::{Float32, Float64},
5 Value,
6};
7
8macro_rules! primitive_eq {
9 ($($val:ident($ty:ty)),+) => {
10 $(
11 impl PartialEq<Value> for $ty {
12 fn eq(&self, other: &Value) -> bool {
13 if let Value::$val(n) = other {
14 self == n
15 } else {
16 unreachable!("type mismatch")
17 }
18 }
19 }
20 impl PartialEq<$ty> for Value {
21 fn eq(&self, other: &$ty) -> bool {
22 if let Value::$val(n) = self {
23 n == other
24 } else {
25 unreachable!("type mismatch")
26 }
27 }
28 }
29
30 impl PartialEq<&Value> for $ty {
31 fn eq(&self, other: &&Value) -> bool {
32 if let Value::$val(n) = other {
33 self == n
34 } else {
35 unreachable!("type mismatch")
36 }
37 }
38 }
39 impl PartialEq<$ty> for &Value {
40 fn eq(&self, other: &$ty) -> bool {
41 if let Value::$val(n) = self {
42 n == other
43 } else {
44 unreachable!("type mismatch")
45 }
46 }
47 }
48
49 impl PartialEq<&mut Value> for $ty {
50 fn eq(&self, other: &&mut Value) -> bool {
51 if let Value::$val(n) = other {
52 self == n
53 } else {
54 unreachable!("type mismatch")
55 }
56 }
57 }
58 impl PartialEq<$ty> for &mut Value {
59 fn eq(&self, other: &$ty) -> bool {
60 if let Value::$val(n) = self {
61 n == other
62 } else {
63 unreachable!("type mismatch")
64 }
65 }
66 }
67 )+
68 };
69}
70
71macro_rules! primitive_ord {
72 ($($val:ident($ty:ty)),+) => {
73 $(
74 impl PartialOrd<Value> for $ty {
75 fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
76 if let Value::$val(n) = other {
77 self.partial_cmp(n)
78 } else {
79 None
80 }
81 }
82 }
83 impl PartialOrd<$ty> for Value {
84 fn partial_cmp(&self, other: &$ty) -> Option<Ordering> {
85 if let Value::$val(n) = self {
86 n.partial_cmp(other)
87 } else {
88 None
89 }
90 }
91 }
92
93 impl PartialOrd<&Value> for $ty {
94 fn partial_cmp(&self, other: &&Value) -> Option<Ordering> {
95 if let Value::$val(n) = other {
96 self.partial_cmp(n)
97 } else {
98 None
99 }
100 }
101 }
102 impl PartialOrd<$ty> for &Value {
103 fn partial_cmp(&self, other: &$ty) -> Option<Ordering> {
104 if let Value::$val(n) = self {
105 n.partial_cmp(other)
106 } else {
107 None
108 }
109 }
110 }
111
112 impl PartialOrd<&mut Value> for $ty {
113 fn partial_cmp(&self, other: &&mut Value) -> Option<Ordering> {
114 if let Value::$val(n) = other {
115 self.partial_cmp(n)
116 } else {
117 None
118 }
119 }
120 }
121 impl PartialOrd<$ty> for &mut Value {
122 fn partial_cmp(&self, other: &$ty) -> Option<Ordering> {
123 if let Value::$val(n) = self {
124 n.partial_cmp(other)
125 } else {
126 None
127 }
128 }
129 }
130 )+
131 };
132}
133
134primitive_eq!(
135 Uint8(u8),
136 Int8(i8),
137 Uint16(u16),
138 Int16(i16),
139 Uint32(u32),
140 Int32(i32),
141 Uint64(u64),
142 Int64(i64),
143 String(String),
144 Boolean(bool),
145 Char(char)
146);
147
148primitive_ord!(
149 Uint8(u8),
150 Int8(i8),
151 Uint16(u16),
152 Int16(i16),
153 Uint32(u32),
154 Int32(i32),
155 Uint64(u64),
156 Int64(i64),
157 String(String),
158 Boolean(bool),
159 Char(char)
160);
161
162impl PartialEq<Value> for f32 {
163 fn eq(&self, other: &Value) -> bool {
164 if let Value::Float32(Float32(f)) = other {
165 if self.is_finite() && f.is_finite() {
166 self == f
167 } else {
168 false
169 }
170 } else {
171 unreachable!("type mismatch")
172 }
173 }
174}
175
176impl PartialEq<f32> for Value {
177 fn eq(&self, other: &f32) -> bool {
178 if let Value::Float32(Float32(f)) = self {
179 if f.is_finite() && other.is_finite() {
180 f == other
181 } else {
182 false
183 }
184 } else {
185 unreachable!("type mismatch")
186 }
187 }
188}
189
190impl PartialEq<&Value> for f32 {
191 fn eq(&self, other: &&Value) -> bool {
192 if let Value::Float32(Float32(f)) = other {
193 if self.is_finite() && f.is_finite() {
194 self == f
195 } else {
196 false
197 }
198 } else {
199 unreachable!("type mismatch")
200 }
201 }
202}
203
204impl PartialEq<f32> for &Value {
205 fn eq(&self, other: &f32) -> bool {
206 if let Value::Float32(Float32(f)) = self {
207 if f.is_finite() && other.is_finite() {
208 f == other
209 } else {
210 false
211 }
212 } else {
213 unreachable!("type mismatch")
214 }
215 }
216}
217impl PartialEq<&mut Value> for f32 {
218 fn eq(&self, other: &&mut Value) -> bool {
219 if let Value::Float32(Float32(f)) = other {
220 if self.is_finite() && f.is_finite() {
221 self == f
222 } else {
223 false
224 }
225 } else {
226 unreachable!("type mismatch")
227 }
228 }
229}
230
231impl PartialEq<f32> for &mut Value {
232 fn eq(&self, other: &f32) -> bool {
233 if let Value::Float32(Float32(f)) = self {
234 if f.is_finite() && other.is_finite() {
235 f == other
236 } else {
237 false
238 }
239 } else {
240 unreachable!("type mismatch")
241 }
242 }
243}
244
245impl PartialEq<Value> for f64 {
246 fn eq(&self, other: &Value) -> bool {
247 if let Value::Float64(Float64(f)) = other {
248 if self.is_finite() && f.is_finite() {
249 self == f
250 } else {
251 false
252 }
253 } else {
254 unreachable!("type mismatch")
255 }
256 }
257}
258
259impl PartialEq<f64> for Value {
260 fn eq(&self, other: &f64) -> bool {
261 if let Value::Float64(Float64(f)) = self {
262 if f.is_finite() && other.is_finite() {
263 f == other
264 } else {
265 false
266 }
267 } else {
268 unreachable!("type mismatch")
269 }
270 }
271}
272
273impl PartialEq<&Value> for f64 {
274 fn eq(&self, other: &&Value) -> bool {
275 if let Value::Float64(Float64(f)) = other {
276 if self.is_finite() && f.is_finite() {
277 self == f
278 } else {
279 false
280 }
281 } else {
282 unreachable!("type mismatch")
283 }
284 }
285}
286
287impl PartialEq<f64> for &Value {
288 fn eq(&self, other: &f64) -> bool {
289 if let Value::Float64(Float64(f)) = self {
290 if f.is_finite() && other.is_finite() {
291 f == other
292 } else {
293 false
294 }
295 } else {
296 unreachable!("type mismatch")
297 }
298 }
299}
300
301impl PartialEq<&mut Value> for f64 {
302 fn eq(&self, other: &&mut Value) -> bool {
303 if let Value::Float64(Float64(f)) = other {
304 if self.is_finite() && f.is_finite() {
305 self == f
306 } else {
307 false
308 }
309 } else {
310 unreachable!("type mismatch")
311 }
312 }
313}
314
315impl PartialEq<f64> for &mut Value {
316 fn eq(&self, other: &f64) -> bool {
317 if let Value::Float64(Float64(f)) = self {
318 if f.is_finite() && other.is_finite() {
319 f == other
320 } else {
321 false
322 }
323 } else {
324 unreachable!("type mismatch")
325 }
326 }
327}
328
329#[test]
330fn all() {
331 let mut value = Value::Uint8(10);
332
333 assert!(value == 10_u8);
334 assert!(value > 9_u8);
335 assert!(&value == 10_u8);
336 assert!(&value > 9_u8);
337 assert!(&mut value == 10_u8);
338 assert!(&mut value > 9_u8);
339
340 let value = Value::Float32(Float32(1.1));
341 let f = 1.1_f32;
342 assert!(value == f);
343
344 let value_nan = Value::Float32(Float32(f32::NAN));
345 let f_nan = f32::NAN;
346 assert!(value_nan != f_nan);
347}
348
349#[test]
350#[should_panic]
351fn type_mismatch() {
352 let value = Value::Uint8(10);
353 assert!(value == 10_i8);
354}