1use ref_cast::RefCast;
6use serde_json::{Map, Value as Json};
7use valuable::{Listable, Mappable, Valuable, Value, Visit};
8
9#[derive(RefCast)]
10#[repr(transparent)]
11pub struct JsonValuable(pub Json);
12
13impl JsonValuable {
14 fn new(json: &Json) -> &JsonValuable {
15 JsonValuable::ref_cast(json)
16 }
17}
18
19#[cfg(tracing_unstable)]
20impl Valuable for JsonValuable {
21 fn as_value(&self) -> Value<'_> {
22 match self.0 {
23 Json::Array(ref array) => JsonValuableArray::new(array).as_value(),
24 Json::Bool(ref value) => value.as_value(),
25 Json::Number(ref num) => {
26 if num.is_f64()
27 && let Some(num) = num.as_f64()
28 {
29 Value::F64(num)
30 } else if num.is_i64()
31 && let Some(num) = num.as_i64()
32 {
33 Value::I64(num)
34 } else {
35 unreachable!()
36 }
37 }
38 Json::Null => Value::Unit,
39 Json::String(ref s) => s.as_value(),
40 Json::Object(ref object) => JsonValuableMap::new(object).as_value(),
41 }
42 }
43
44 fn visit(&self, visit: &mut dyn Visit) {
45 match self.0 {
46 Json::Array(ref array) => JsonValuableArray::new(array).visit(visit),
47 Json::Bool(ref value) => value.visit(visit),
48 Json::Number(ref num) => {
49 if num.is_f64()
50 && let Some(num) = num.as_f64()
51 {
52 num.visit(visit);
53 } else if num.is_i64()
54 && let Some(num) = num.as_i64()
55 {
56 num.visit(visit);
57 } else {
58 unreachable!()
59 }
60 }
61 Json::Null => Value::Unit.visit(visit),
62 Json::String(ref s) => s.visit(visit),
63 Json::Object(ref object) => JsonValuableMap::new(object).visit(visit),
64 }
65 }
66}
67
68#[derive(RefCast)]
69#[repr(transparent)]
70pub struct JsonValuableMap(pub Map<String, Json>);
71
72impl JsonValuableMap {
73 fn new(map: &Map<String, Json>) -> &JsonValuableMap {
74 JsonValuableMap::ref_cast(map)
75 }
76}
77
78#[cfg(tracing_unstable)]
79impl Valuable for JsonValuableMap {
80 fn as_value(&self) -> Value<'_> {
81 Value::Mappable(self)
82 }
83
84 fn visit(&self, visit: &mut dyn Visit) {
85 for (k, v) in &self.0 {
86 visit.visit_entry(k.as_value(), JsonValuable::new(v).as_value());
87 }
88 }
89}
90
91#[cfg(tracing_unstable)]
92impl Mappable for JsonValuableMap {
93 fn size_hint(&self) -> (usize, Option<usize>) {
94 let len = self.0.len();
95 (len, Some(len))
96 }
97}
98
99#[derive(RefCast)]
100#[repr(transparent)]
101pub struct JsonValuableArray(pub Vec<Json>);
102
103impl JsonValuableArray {
104 fn new(arr: &Vec<Json>) -> &JsonValuableArray {
105 JsonValuableArray::ref_cast(arr)
106 }
107}
108
109#[cfg(tracing_unstable)]
110impl Valuable for JsonValuableArray {
111 fn as_value(&self) -> Value<'_> {
112 Value::Listable(self)
113 }
114
115 fn visit(&self, visit: &mut dyn Visit) {
116 for v in &self.0 {
117 visit.visit_value(JsonValuable::new(v).as_value());
118 }
119 }
120}
121
122#[cfg(tracing_unstable)]
123impl Listable for JsonValuableArray {
124 fn size_hint(&self) -> (usize, Option<usize>) {
125 let len = self.0.len();
126 (len, Some(len))
127 }
128}