qubit_value/value/
value_identity.rs1use std::hash::{
11 Hash,
12 Hasher,
13};
14
15use super::{
16 Value,
17 ValueRepr,
18};
19#[cfg(feature = "big-decimal")]
20use crate::identity::hash_big_decimal;
21use crate::identity::{
22 canonical_f32_bits,
23 canonical_f64_bits,
24 hash_string_map,
25};
26#[cfg(feature = "json")]
27use crate::identity::{
28 hash_json,
29 json_eq,
30};
31
32macro_rules! payload_eq {
33 (Float32, $left:expr, $right:expr) => {
34 canonical_f32_bits(*$left) == canonical_f32_bits(*$right)
35 };
36 (Float64, $left:expr, $right:expr) => {
37 canonical_f64_bits(*$left) == canonical_f64_bits(*$right)
38 };
39 (Json, $left:expr, $right:expr) => {
40 json_eq($left, $right)
41 };
42 ($variant:ident, $left:expr, $right:expr) => {
43 $left == $right
44 };
45}
46
47macro_rules! hash_payload {
48 (Float32, $value:expr, $state:expr) => {
49 canonical_f32_bits(*$value).hash($state)
50 };
51 (Float64, $value:expr, $state:expr) => {
52 canonical_f64_bits(*$value).hash($state)
53 };
54 (BigDecimal, $value:expr, $state:expr) => {
55 hash_big_decimal($value, $state)
56 };
57 (StringMap, $value:expr, $state:expr) => {
58 hash_string_map($value, $state)
59 };
60 (Json, $value:expr, $state:expr) => {
61 hash_json($value, $state)
62 };
63 ($variant:ident, $value:expr, $state:expr) => {
64 $value.hash($state)
65 };
66}
67
68macro_rules! impl_value_identity {
69 (
70 ;
71 $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?
72 ) => {
73 impl PartialEq for Value {
74 fn eq(&self, other: &Self) -> bool {
75 match (&self.repr, &other.repr) {
76 (ValueRepr::Unset(left), ValueRepr::Unset(right)) => left == right,
77 $($(#[$cfg])*
78 (ValueRepr::$variant(left), ValueRepr::$variant(right)) => {
79 payload_eq!($variant, left, right)
80 },)+
81 _ => false,
82 }
83 }
84 }
85
86 impl Eq for Value {}
87
88 impl Hash for Value {
89 fn hash<H: Hasher>(&self, state: &mut H) {
90 std::mem::discriminant(&self.repr).hash(state);
91 match &self.repr {
92 ValueRepr::Unset(data_type) => data_type.hash(state),
93 $($(#[$cfg])*
94 ValueRepr::$variant(value) => hash_payload!($variant, value, state),)+
95 }
96 }
97 }
98 };
99}
100
101for_each_value_type!(impl_value_identity);