1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use generic_json::{Json, JsonHash, ValueRef};
use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
ops::Deref,
};
mod build;
pub use build::*;
pub enum AsArrayItem<'a, J: Json> {
NotArray(&'a J),
Array(<J::Array as cc_traits::CollectionRef>::ItemRef<'a>),
}
impl<'a, J: Json> Deref for AsArrayItem<'a, J> {
type Target = J;
fn deref(&self) -> &J {
match self {
Self::NotArray(i) => i,
Self::Array(i) => i.deref(),
}
}
}
pub enum AsArray<'a, J: Json> {
NotArray(Option<&'a J>),
Array(<J::Array as cc_traits::Iter>::Iter<'a>),
}
impl<'a, J: Json> Iterator for AsArray<'a, J> {
type Item = AsArrayItem<'a, J>;
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::NotArray(item) => item.take().map(AsArrayItem::NotArray),
Self::Array(ary) => ary.next().map(AsArrayItem::Array),
}
}
}
pub fn as_array<J: Json>(json: &J) -> (AsArray<J>, usize) {
use cc_traits::{Iter, Len};
match json.as_value_ref() {
ValueRef::Array(ary) => (AsArray::Array(ary.iter()), ary.len()),
_ => (AsArray::NotArray(Some(json)), 1),
}
}
pub fn hash_json<J: JsonHash, H: Hasher>(json: &J, hasher: &mut H) {
use cc_traits::{Iter, MapIter};
match json.as_value_ref() {
ValueRef::Null => (),
ValueRef::Boolean(b) => b.hash(hasher),
ValueRef::Number(n) => n.hash(hasher),
ValueRef::String(s) => s.hash(hasher),
ValueRef::Array(ary) => {
for item in ary.iter() {
hash_json(&*item, hasher)
}
}
ValueRef::Object(obj) => {
let mut hash = 0;
for (key, value) in obj.iter() {
let mut h = DefaultHasher::new();
(*key).hash(&mut h);
hash_json(&*value, &mut h);
hash = u64::wrapping_add(hash, h.finish());
}
hasher.write_u64(hash);
}
}
}