1use crate::Value;
2
3macro_rules! implpartialeq {
4 ($($t:ty),+ $(,)?) => {
5 $(
6 impl PartialEq<$t> for Value {
7 #[inline]
8 fn eq(&self, other: &$t) -> bool {
9 if let Some(i) = self.as_integer::<$t>() {
10 &i == other
11 } else {
12 false
13 }
14 }
15 }
16
17 impl PartialEq<$t> for &Value {
18 #[inline]
19 fn eq(&self, other: &$t) -> bool {
20 if let Some(i) = self.as_integer::<$t>() {
21 &i == other
22 } else {
23 false
24 }
25 }
26 }
27 )+
28 };
29}
30
31implpartialeq! {
32 u128,
33 u64,
34 u32,
35 u16,
36 u8,
37 i128,
38 i64,
39 i32,
40 i16,
41 i8,
42}
43
44impl PartialEq<String> for Value {
45 #[inline]
46 fn eq(&self, other: &String) -> bool {
47 if let Some(i) = self.as_text() {
48 i == other
49 } else {
50 false
51 }
52 }
53}
54
55impl PartialEq<String> for &Value {
56 #[inline]
57 fn eq(&self, other: &String) -> bool {
58 if let Some(i) = self.as_str() {
59 i == other
60 } else {
61 false
62 }
63 }
64}
65
66impl PartialEq<&str> for Value {
67 #[inline]
68 fn eq(&self, other: &&str) -> bool {
69 if let Some(i) = self.as_str() {
70 &i == other
71 } else {
72 false
73 }
74 }
75}
76
77impl PartialEq<&str> for &Value {
78 #[inline]
79 fn eq(&self, other: &&str) -> bool {
80 if let Some(i) = self.as_str() {
81 &i == other
82 } else {
83 false
84 }
85 }
86}
87
88impl PartialEq<f64> for Value {
89 #[inline]
90 fn eq(&self, other: &f64) -> bool {
91 if let Some(i) = self.as_float() {
92 &i == other
93 } else {
94 false
95 }
96 }
97}
98
99impl PartialEq<f64> for &Value {
100 #[inline]
101 fn eq(&self, other: &f64) -> bool {
102 if let Some(i) = self.as_float() {
103 &i == other
104 } else {
105 false
106 }
107 }
108}
109
110impl PartialEq<Vec<u8>> for Value {
111 #[inline]
112 fn eq(&self, other: &Vec<u8>) -> bool {
113 self.as_bytes_slice() == Ok(other.as_slice())
114 }
115}
116impl PartialEq<Vec<u8>> for &Value {
117 #[inline]
118 fn eq(&self, other: &Vec<u8>) -> bool {
119 self.as_bytes_slice() == Ok(other.as_slice())
120 }
121}
122
123macro_rules! impl_bytes_array_eq {
124 ($($n:expr),+ $(,)?) => {$(
125 impl PartialEq<[u8; $n]> for Value {
126 #[inline]
127 fn eq(&self, other: &[u8; $n]) -> bool {
128 self.as_bytes_slice() == Ok(other.as_slice())
129 }
130 }
131 impl PartialEq<[u8; $n]> for &Value {
132 #[inline]
133 fn eq(&self, other: &[u8; $n]) -> bool {
134 self.as_bytes_slice() == Ok(other.as_slice())
135 }
136 }
137 )+};
138}
139impl_bytes_array_eq! { 20, 32, 36 }
140
141impl Value {
142 #[inline]
157 pub fn equal_underlying_data(&self, other: &Value) -> bool {
158 if let (Ok(a), Ok(b)) = (self.as_bytes_slice(), other.as_bytes_slice()) {
160 return a == b;
161 }
162
163 if let (Some(a), Some(b)) = (self.as_i128_unified(), other.as_i128_unified()) {
165 return a == b;
166 }
167
168 self == other
170 }
171}
172
173#[cfg(test)]
174mod tests {
175 use crate::Value;
176
177 #[test]
180 fn u8_eq() {
181 assert_eq!(Value::U8(42), 42u8);
182 assert_ne!(Value::U8(42), 43u8);
183 }
184
185 #[test]
186 fn i8_eq() {
187 assert_eq!(Value::I8(-1), -1i8);
188 assert_ne!(Value::I8(-1), 0i8);
189 }
190
191 #[test]
192 fn u16_eq() {
193 assert_eq!(Value::U16(1000), 1000u16);
194 assert_ne!(Value::U16(1000), 999u16);
195 }
196
197 #[test]
198 fn i16_eq() {
199 assert_eq!(Value::I16(-500), -500i16);
200 assert_ne!(Value::I16(-500), 500i16);
201 }
202
203 #[test]
204 fn u32_eq() {
205 assert_eq!(Value::U32(100_000), 100_000u32);
206 assert_ne!(Value::U32(100_000), 0u32);
207 }
208
209 #[test]
210 fn i32_eq() {
211 assert_eq!(Value::I32(-100), -100i32);
212 assert_ne!(Value::I32(-100), 100i32);
213 }
214
215 #[test]
216 fn u64_eq() {
217 assert_eq!(Value::U64(u64::MAX), u64::MAX);
218 assert_ne!(Value::U64(0), 1u64);
219 }
220
221 #[test]
222 fn i64_eq() {
223 assert_eq!(Value::I64(i64::MIN), i64::MIN);
224 assert_ne!(Value::I64(0), 1i64);
225 }
226
227 #[test]
228 fn u128_eq() {
229 assert_eq!(Value::U128(u128::MAX), u128::MAX);
230 assert_ne!(Value::U128(0), 1u128);
231 }
232
233 #[test]
234 fn i128_eq() {
235 assert_eq!(Value::I128(i128::MIN), i128::MIN);
236 assert_ne!(Value::I128(0), 1i128);
237 }
238
239 #[test]
242 fn u8_value_eq_u64_type() {
243 assert_eq!(Value::U8(10), 10u64);
245 }
246
247 #[test]
248 fn u64_value_eq_u8_type_when_fits() {
249 assert_eq!(Value::U64(200), 200u8);
250 }
251
252 #[test]
253 fn u64_value_ne_u8_type_when_overflow() {
254 assert_ne!(Value::U64(256), 0u8); }
257
258 #[test]
259 fn i8_value_eq_i64_type() {
260 assert_eq!(Value::I8(-10), -10i64);
261 }
262
263 #[test]
264 fn non_integer_ne_integer() {
265 assert_ne!(Value::Text("hello".to_string()), 0u64);
266 assert_ne!(Value::Null, 0i32);
267 assert_ne!(Value::Bool(true), 1u8);
268 }
269
270 #[test]
273 fn string_eq() {
274 let val = Value::Text("hello".to_string());
275 assert_eq!(val, "hello".to_string());
276 assert_ne!(val, "world".to_string());
277 }
278
279 #[test]
280 fn non_text_ne_string() {
281 assert_ne!(Value::U8(0), "0".to_string());
282 assert_ne!(Value::Null, "".to_string());
283 }
284
285 #[test]
288 fn str_ref_eq() {
289 let val = Value::Text("test".to_string());
290 assert_eq!(val, "test");
291 assert_ne!(val, "other");
292 }
293
294 #[test]
295 fn non_text_ne_str_ref() {
296 assert_ne!(Value::Bool(false), "false");
297 }
298
299 #[test]
302 fn float_eq() {
303 assert_eq!(Value::Float(3.14), 3.14f64);
304 assert_ne!(Value::Float(3.14), 3.15f64);
305 }
306
307 #[test]
308 fn integer_eq_float_through_as_float() {
309 assert_eq!(Value::U64(10), 10.0f64);
311 }
312
313 #[test]
314 fn non_numeric_ne_float() {
315 assert_ne!(Value::Text("3.14".to_string()), 3.14f64);
316 }
317
318 #[test]
321 fn bytes_eq_vec_u8() {
322 let data = vec![1, 2, 3];
323 assert_eq!(Value::Bytes(data.clone()), data);
324 }
325
326 #[test]
327 fn bytes_ne_vec_u8() {
328 assert_ne!(Value::Bytes(vec![1, 2, 3]), vec![1, 2, 4]);
329 }
330
331 #[test]
332 fn identifier_eq_vec_u8() {
333 let id = [42u8; 32];
334 assert_eq!(Value::Identifier(id), id.to_vec());
335 }
336
337 #[test]
338 fn bytes20_eq_vec_u8() {
339 let b = [5u8; 20];
340 assert_eq!(Value::Bytes20(b), b.to_vec());
341 }
342
343 #[test]
344 fn non_bytes_ne_vec_u8() {
345 assert_ne!(Value::U8(1), vec![1u8]);
346 }
347
348 #[test]
351 fn bytes32_eq_array() {
352 let b = [0xffu8; 32];
353 assert_eq!(Value::Bytes32(b), b);
354 }
355
356 #[test]
357 fn identifier_eq_array_32() {
358 let id = [7u8; 32];
359 assert_eq!(Value::Identifier(id), id);
360 }
361
362 #[test]
363 fn bytes_eq_array_32() {
364 let data = [3u8; 32];
365 assert_eq!(Value::Bytes(data.to_vec()), data);
366 }
367
368 #[test]
369 fn non_bytes_ne_array_32() {
370 assert_ne!(Value::Null, [0u8; 32]);
371 }
372
373 #[test]
376 fn bytes20_eq_array_20() {
377 let b = [1u8; 20];
378 assert_eq!(Value::Bytes20(b), b);
379 }
380
381 #[test]
384 fn bytes36_eq_array_36() {
385 let b = [2u8; 36];
386 assert_eq!(Value::Bytes36(b), b);
387 }
388
389 #[test]
392 fn ref_value_eq_integer() {
393 let val = Value::U64(42);
394 assert_eq!(&val, 42u64);
395 }
396
397 #[test]
398 fn ref_value_eq_string() {
399 let val = Value::Text("hi".to_string());
400 assert_eq!(&val, "hi".to_string());
401 }
402
403 #[test]
404 fn ref_value_eq_str_ref() {
405 let val = Value::Text("hi".to_string());
406 assert_eq!(&val, "hi");
407 }
408
409 #[test]
410 fn ref_value_eq_float() {
411 let val = Value::Float(1.0);
412 assert_eq!(&val, 1.0f64);
413 }
414
415 #[test]
416 fn ref_value_eq_vec_u8() {
417 let val = Value::Bytes(vec![10, 20]);
418 assert_eq!(&val, vec![10u8, 20]);
419 }
420
421 #[test]
422 fn ref_value_eq_array_32() {
423 let b = [0u8; 32];
424 let val = Value::Bytes32(b);
425 assert_eq!(&val, b);
426 }
427
428 #[test]
431 fn equal_underlying_data_bytes_vs_identifier_same_data() {
432 let data = [42u8; 32];
433 let bytes = Value::Bytes(data.to_vec());
434 let ident = Value::Identifier(data);
435 assert!(bytes.equal_underlying_data(&ident));
436 assert!(ident.equal_underlying_data(&bytes));
437 }
438
439 #[test]
440 fn equal_underlying_data_bytes_vs_identifier_different_data() {
441 let bytes = Value::Bytes(vec![0u8; 32]);
442 let ident = Value::Identifier([1u8; 32]);
443 assert!(!bytes.equal_underlying_data(&ident));
444 }
445
446 #[test]
447 fn equal_underlying_data_bytes32_vs_identifier() {
448 let data = [99u8; 32];
449 let b32 = Value::Bytes32(data);
450 let ident = Value::Identifier(data);
451 assert!(b32.equal_underlying_data(&ident));
452 }
453
454 #[test]
455 fn equal_underlying_data_bytes20_vs_bytes() {
456 let data = [5u8; 20];
457 let b20 = Value::Bytes20(data);
458 let bytes = Value::Bytes(data.to_vec());
459 assert!(b20.equal_underlying_data(&bytes));
460 }
461
462 #[test]
463 fn equal_underlying_data_u8_vs_u64_same_value() {
464 let a = Value::U8(10);
465 let b = Value::U64(10);
466 assert!(a.equal_underlying_data(&b));
467 }
468
469 #[test]
470 fn equal_underlying_data_i8_vs_i128_same_value() {
471 let a = Value::I8(-5);
472 let b = Value::I128(-5);
473 assert!(a.equal_underlying_data(&b));
474 }
475
476 #[test]
477 fn equal_underlying_data_u8_vs_u64_different_value() {
478 let a = Value::U8(10);
479 let b = Value::U64(20);
480 assert!(!a.equal_underlying_data(&b));
481 }
482
483 #[test]
484 fn equal_underlying_data_u16_vs_i32_same_value() {
485 let a = Value::U16(100);
486 let b = Value::I32(100);
487 assert!(a.equal_underlying_data(&b));
488 }
489
490 #[test]
491 fn equal_underlying_data_negative_i8_vs_u64() {
492 let a = Value::I8(-1);
494 let b = Value::U64(255);
495 assert!(!a.equal_underlying_data(&b));
496 }
497
498 #[test]
499 fn equal_underlying_data_same_variant_same_value() {
500 let a = Value::U64(42);
501 let b = Value::U64(42);
502 assert!(a.equal_underlying_data(&b));
503 }
504
505 #[test]
506 fn equal_underlying_data_fallback_to_partial_eq() {
507 let a = Value::Text("hello".to_string());
509 let b = Value::Text("hello".to_string());
510 assert!(a.equal_underlying_data(&b));
511
512 let c = Value::Text("world".to_string());
513 assert!(!a.equal_underlying_data(&c));
514 }
515
516 #[test]
517 fn equal_underlying_data_null_vs_null() {
518 assert!(Value::Null.equal_underlying_data(&Value::Null));
519 }
520
521 #[test]
522 fn equal_underlying_data_different_types_not_equal() {
523 let a = Value::Text("42".to_string());
525 let b = Value::U64(42);
526 assert!(!a.equal_underlying_data(&b));
527 }
528
529 #[test]
530 fn equal_underlying_data_bool_vs_bool() {
531 assert!(Value::Bool(true).equal_underlying_data(&Value::Bool(true)));
532 assert!(!Value::Bool(true).equal_underlying_data(&Value::Bool(false)));
533 }
534
535 #[test]
536 fn equal_underlying_data_float_vs_float() {
537 assert!(Value::Float(1.5).equal_underlying_data(&Value::Float(1.5)));
538 assert!(!Value::Float(1.5).equal_underlying_data(&Value::Float(2.5)));
539 }
540}