use std::hash::{
BuildHasher,
BuildHasherDefault,
Hash,
Hasher,
};
type IdentityHasher =
BuildHasherDefault<std::collections::hash_map::DefaultHasher>;
#[must_use]
#[inline(always)]
pub(crate) fn json_eq(
left: &serde_json::Value,
right: &serde_json::Value,
) -> bool {
left == right
}
pub(crate) fn hash_json<H: Hasher>(value: &serde_json::Value, state: &mut H) {
match value {
serde_json::Value::Null => 0_u8.hash(state),
serde_json::Value::Bool(value) => {
1_u8.hash(state);
value.hash(state);
}
serde_json::Value::Number(value) => {
2_u8.hash(state);
value.hash(state);
}
serde_json::Value::String(value) => {
3_u8.hash(state);
value.hash(state);
}
serde_json::Value::Array(values) => {
4_u8.hash(state);
values.len().hash(state);
for value in values {
hash_json(value, state);
}
}
serde_json::Value::Object(values) => {
5_u8.hash(state);
values.len().hash(state);
let mut sum = 0_u64;
let mut xor = 0_u64;
for (key, value) in values {
let mut entry = IdentityHasher::default().build_hasher();
key.hash(&mut entry);
hash_json(value, &mut entry);
let hash = entry.finish();
sum = sum.wrapping_add(hash);
xor ^= hash.rotate_left(17);
}
sum.hash(state);
xor.hash(state);
}
}
}