qubit_value/multi_values/
multi_values_identity.rs1use std::hash::Hash;
11use std::hash::Hasher;
12use std::mem::discriminant;
13
14use super::MultiValuesRepr;
15use super::multi_values::MultiValues;
16use crate::identity::canonical_f32_bits;
17use crate::identity::canonical_f64_bits;
18#[cfg(feature = "big-decimal")]
19use crate::identity::hash_big_decimal;
20#[cfg(feature = "json")]
21use crate::identity::hash_json;
22use crate::identity::hash_string_map;
23#[cfg(feature = "json")]
24use crate::identity::json_eq;
25
26macro_rules! payloads_eq {
28 (Float32, $left:expr, $right:expr) => {
29 $left.len() == $right.len()
30 && $left
31 .iter()
32 .zip($right)
33 .all(|(left, right)| canonical_f32_bits(*left) == canonical_f32_bits(*right))
34 };
35 (Float64, $left:expr, $right:expr) => {
36 $left.len() == $right.len()
37 && $left
38 .iter()
39 .zip($right)
40 .all(|(left, right)| canonical_f64_bits(*left) == canonical_f64_bits(*right))
41 };
42 (Json, $left:expr, $right:expr) => {
43 $left.len() == $right.len()
44 && $left
45 .iter()
46 .zip($right)
47 .all(|(left, right)| json_eq(left, right))
48 };
49 ($variant:ident, $left:expr, $right:expr) => {
50 $left == $right
51 };
52}
53
54macro_rules! hash_payloads {
56 (Float32, $values:expr, $state:expr) => {{
57 $values.len().hash($state);
58 for value in $values {
59 canonical_f32_bits(*value).hash($state);
60 }
61 }};
62 (Float64, $values:expr, $state:expr) => {{
63 $values.len().hash($state);
64 for value in $values {
65 canonical_f64_bits(*value).hash($state);
66 }
67 }};
68 (BigDecimal, $values:expr, $state:expr) => {{
69 $values.len().hash($state);
70 for value in $values {
71 hash_big_decimal(value, $state);
72 }
73 }};
74 (StringMap, $values:expr, $state:expr) => {{
75 $values.len().hash($state);
76 for value in $values {
77 hash_string_map(value, $state);
78 }
79 }};
80 (Json, $values:expr, $state:expr) => {{
81 $values.len().hash($state);
82 for value in $values {
83 hash_json(value, $state);
84 }
85 }};
86 ($variant:ident, $values:expr, $state:expr) => {
87 $values.hash($state)
88 };
89}
90
91#[cfg(feature = "json")]
93macro_rules! non_json_hash_payload {
94 (Json, $value:expr, $state:expr) => {{
95 let _ = $value;
96 unreachable!("JSON payload hashing is handled by MultiValues::hash_with_json_budget")
97 }};
98 ($variant:ident, $value:expr, $state:expr) => {
99 hash_payloads!($variant, $value, $state)
100 };
101}
102
103#[cfg(feature = "json")]
105macro_rules! non_json_payload_match {
106 ($repr:expr, $state:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal $(, $_wire:tt)*)),+ $(,)?) => {
107 match $repr {
108 MultiValuesRepr::Unset(data_type) => data_type.hash($state),
109 $($(#[$cfg])* MultiValuesRepr::$variant(value) => {
110 non_json_hash_payload!($variant, value, $state)
111 },)+
112 }
113 };
114}
115
116#[cfg(feature = "json")]
133pub(crate) fn hash_non_json_multi_values_payload<H: Hasher>(repr: &MultiValuesRepr, state: &mut H) {
134 for_each_value_type!(non_json_payload_match, repr, state);
135}
136
137macro_rules! impl_multi_values_identity {
139 (
140 ;
141 $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal $(, $_wire:tt)*)),+ $(,)?
142 ) => {
143 impl PartialEq for MultiValues {
144 fn eq(&self, other: &Self) -> bool {
154 match (&self.repr, &other.repr) {
155 (MultiValuesRepr::Unset(left), MultiValuesRepr::Unset(right)) => left == right,
156 $($(#[$cfg])*
157 (MultiValuesRepr::$variant(left), MultiValuesRepr::$variant(right)) => {
158 payloads_eq!($variant, left, right)
159 },)+
160 _ => false,
161 }
162 }
163 }
164
165 impl Eq for MultiValues {}
166
167 impl Hash for MultiValues {
168 fn hash<H: Hasher>(&self, state: &mut H) {
178 discriminant(&self.repr).hash(state);
179 match &self.repr {
180 MultiValuesRepr::Unset(data_type) => data_type.hash(state),
181 $($(#[$cfg])*
182 MultiValuesRepr::$variant(values) => {
183 hash_payloads!($variant, values, state)
184 },)+
185 }
186 }
187 }
188 };
189}
190
191for_each_value_type!(impl_multi_values_identity);