1use std::collections::hash_map::DefaultHasher;
2use std::hash::{
3 Hash,
4 Hasher,
5};
6
7use serde_json as json;
8
9struct HashableJsonValue<'a>(&'a json::Value);
10
11impl Hash for HashableJsonValue<'_> {
12 fn hash<H: Hasher>(&self, state: &mut H) {
13 match self.0 {
14 json::Value::Null => None::<()>.hash(state),
15 json::Value::Bool(b) => b.hash(state),
16 json::Value::Number(n) => n.hash(state),
17 json::Value::String(s) => s.hash(state),
18 json::Value::Array(a) => {
19 for v in a {
20 HashableJsonValue(v).hash(state);
21 }
22 },
23 json::Value::Object(o) => {
24 for (k, v) in o {
25 k.hash(state);
26 HashableJsonValue(v).hash(state);
27 }
28 },
29 }
30 }
31}
32
33pub fn hash_option(maybe_v: Option<&json::Value>) -> u64 {
34 let mut s = DefaultHasher::new();
35 match maybe_v {
36 None => HashableJsonValue(&json::Value::Null).hash(&mut s),
37 Some(v) => HashableJsonValue(v).hash(&mut s),
38 }
39 s.finish()
40}
41
42pub fn hash(v: &json::Value) -> u64 {
43 let mut s = DefaultHasher::new();
44 HashableJsonValue(v).hash(&mut s);
45 s.finish()
46}