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