qubit_value/multi_values/
multi_values_identity.rs1use std::hash::{
11 Hash,
12 Hasher,
13};
14
15use super::multi_values::{
16 MultiValues,
17 MultiValuesRepr,
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! payloads_eq {
34 (Float32, $left:expr, $right:expr) => {
35 $left.len() == $right.len()
36 && $left.iter().zip($right).all(|(left, right)| {
37 canonical_f32_bits(*left) == canonical_f32_bits(*right)
38 })
39 };
40 (Float64, $left:expr, $right:expr) => {
41 $left.len() == $right.len()
42 && $left.iter().zip($right).all(|(left, right)| {
43 canonical_f64_bits(*left) == canonical_f64_bits(*right)
44 })
45 };
46 (Json, $left:expr, $right:expr) => {
47 $left.len() == $right.len()
48 && $left
49 .iter()
50 .zip($right)
51 .all(|(left, right)| json_eq(left, right))
52 };
53 ($variant:ident, $left:expr, $right:expr) => {
54 $left == $right
55 };
56}
57
58macro_rules! hash_payloads {
60 (Float32, $values:expr, $state:expr) => {{
61 $values.len().hash($state);
62 for value in $values {
63 canonical_f32_bits(*value).hash($state);
64 }
65 }};
66 (Float64, $values:expr, $state:expr) => {{
67 $values.len().hash($state);
68 for value in $values {
69 canonical_f64_bits(*value).hash($state);
70 }
71 }};
72 (BigDecimal, $values:expr, $state:expr) => {{
73 $values.len().hash($state);
74 for value in $values {
75 hash_big_decimal(value, $state);
76 }
77 }};
78 (StringMap, $values:expr, $state:expr) => {{
79 $values.len().hash($state);
80 for value in $values {
81 hash_string_map(value, $state);
82 }
83 }};
84 (Json, $values:expr, $state:expr) => {{
85 $values.len().hash($state);
86 for value in $values {
87 hash_json(value, $state);
88 }
89 }};
90 ($variant:ident, $values:expr, $state:expr) => {
91 $values.hash($state)
92 };
93}
94
95macro_rules! impl_multi_values_identity {
97 (
98 ;
99 $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?
100 ) => {
101 impl PartialEq for MultiValues {
102 fn eq(&self, other: &Self) -> bool {
103 match (&self.repr, &other.repr) {
104 (MultiValuesRepr::Unset(left), MultiValuesRepr::Unset(right)) => left == right,
105 $($(#[$cfg])*
106 (MultiValuesRepr::$variant(left), MultiValuesRepr::$variant(right)) => {
107 payloads_eq!($variant, left, right)
108 },)+
109 _ => false,
110 }
111 }
112 }
113
114 impl Eq for MultiValues {}
115
116 impl Hash for MultiValues {
117 fn hash<H: Hasher>(&self, state: &mut H) {
118 std::mem::discriminant(&self.repr).hash(state);
119 match &self.repr {
120 MultiValuesRepr::Unset(data_type) => data_type.hash(state),
121 $($(#[$cfg])*
122 MultiValuesRepr::$variant(values) => {
123 hash_payloads!($variant, values, state)
124 },)+
125 }
126 }
127 }
128 };
129}
130
131for_each_value_type!(impl_multi_values_identity);