1use std::collections::BTreeMap;
10use std::fmt;
11
12use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
13use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
14
15const MIN_I64_AS_F64: f64 = i64::MIN as f64;
16const MAX_I64_AS_F64: f64 = i64::MAX as f64;
17
18#[derive(Debug, Clone, Default)]
20pub enum JsonValue {
21 #[default]
23 Null,
24 Bool(bool),
26 Int(i64),
28 Double(f64),
31 String(String),
33 Array(Vec<JsonValue>),
35 Object(BTreeMap<String, JsonValue>),
37}
38
39impl JsonValue {
40 pub fn object<const N: usize>(pairs: [(&str, JsonValue); N]) -> Self {
42 JsonValue::Object(
43 pairs
44 .into_iter()
45 .map(|(key, value)| (key.to_owned(), value))
46 .collect(),
47 )
48 }
49
50 pub fn as_object(&self) -> Option<&BTreeMap<String, JsonValue>> {
52 match self {
53 JsonValue::Object(fields) => Some(fields),
54 _ => None,
55 }
56 }
57
58 pub fn as_array(&self) -> Option<&[JsonValue]> {
60 match self {
61 JsonValue::Array(items) => Some(items),
62 _ => None,
63 }
64 }
65
66 pub fn as_str(&self) -> Option<&str> {
68 match self {
69 JsonValue::String(value) => Some(value),
70 _ => None,
71 }
72 }
73
74 pub fn as_bool(&self) -> Option<bool> {
76 match self {
77 JsonValue::Bool(value) => Some(*value),
78 _ => None,
79 }
80 }
81
82 pub fn as_i64(&self) -> Option<i64> {
86 match self {
87 JsonValue::Int(value) => Some(*value),
88 JsonValue::Double(value)
89 if value.is_finite() && *value >= MIN_I64_AS_F64 && *value < MAX_I64_AS_F64 =>
90 {
91 Some(*value as i64)
92 }
93 _ => None,
94 }
95 }
96
97 pub fn as_f64(&self) -> Option<f64> {
99 match self {
100 JsonValue::Double(value) => Some(*value),
101 JsonValue::Int(value) => Some(*value as f64),
102 _ => None,
103 }
104 }
105}
106
107impl From<bool> for JsonValue {
108 fn from(value: bool) -> Self {
109 JsonValue::Bool(value)
110 }
111}
112
113impl From<i64> for JsonValue {
114 fn from(value: i64) -> Self {
115 JsonValue::Int(value)
116 }
117}
118
119impl From<f64> for JsonValue {
120 fn from(value: f64) -> Self {
121 JsonValue::Double(value)
122 }
123}
124
125impl From<&str> for JsonValue {
126 fn from(value: &str) -> Self {
127 JsonValue::String(value.to_owned())
128 }
129}
130
131impl From<String> for JsonValue {
132 fn from(value: String) -> Self {
133 JsonValue::String(value)
134 }
135}
136
137impl From<Vec<JsonValue>> for JsonValue {
138 fn from(value: Vec<JsonValue>) -> Self {
139 JsonValue::Array(value)
140 }
141}
142
143impl From<BTreeMap<String, JsonValue>> for JsonValue {
144 fn from(value: BTreeMap<String, JsonValue>) -> Self {
145 JsonValue::Object(value)
146 }
147}
148
149impl PartialEq for JsonValue {
150 fn eq(&self, other: &Self) -> bool {
151 use JsonValue::{Array, Bool, Double, Int, Null, Object, String};
152 match (self, other) {
153 (Null, Null) => true,
154 (Bool(a), Bool(b)) => a == b,
155 (String(a), String(b)) => a == b,
156 (Array(a), Array(b)) => a == b,
157 (Object(a), Object(b)) => a == b,
158 (Int(a), Int(b)) => a == b,
159 (Double(a), Double(b)) => a == b,
160 (Int(a), Double(b)) => (*a as f64) == *b,
161 (Double(a), Int(b)) => *a == (*b as f64),
162 _ => false,
163 }
164 }
165}
166
167impl Serialize for JsonValue {
168 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
169 match self {
170 JsonValue::Null => serializer.serialize_unit(),
171 JsonValue::Bool(value) => serializer.serialize_bool(*value),
172 JsonValue::Int(value) => serializer.serialize_i64(*value),
173 JsonValue::Double(value) => serializer.serialize_f64(*value),
174 JsonValue::String(value) => serializer.serialize_str(value),
175 JsonValue::Array(items) => {
176 let mut seq = serializer.serialize_seq(Some(items.len()))?;
177 for item in items {
178 seq.serialize_element(item)?;
179 }
180 seq.end()
181 }
182 JsonValue::Object(fields) => {
183 let mut map = serializer.serialize_map(Some(fields.len()))?;
184 for (key, value) in fields {
185 map.serialize_entry(key, value)?;
186 }
187 map.end()
188 }
189 }
190 }
191}
192
193impl<'de> Deserialize<'de> for JsonValue {
194 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
195 deserializer.deserialize_any(JsonValueVisitor)
196 }
197}
198
199struct JsonValueVisitor;
200
201impl<'de> Visitor<'de> for JsonValueVisitor {
202 type Value = JsonValue;
203
204 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
205 formatter.write_str("any JSON value")
206 }
207
208 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
209 Ok(JsonValue::Bool(value))
210 }
211
212 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
213 Ok(JsonValue::Int(value))
214 }
215
216 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
217 if value <= i64::MAX as u64 {
218 Ok(JsonValue::Int(value as i64))
219 } else {
220 Ok(JsonValue::Double(value as f64))
221 }
222 }
223
224 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E> {
225 Ok(i64::try_from(value).map_or_else(|_| JsonValue::Double(value as f64), JsonValue::Int))
226 }
227
228 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E> {
229 Ok(i64::try_from(value).map_or_else(|_| JsonValue::Double(value as f64), JsonValue::Int))
230 }
231
232 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> {
233 Ok(JsonValue::Double(value))
234 }
235
236 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> {
237 Ok(JsonValue::String(value.to_owned()))
238 }
239
240 fn visit_string<E>(self, value: String) -> Result<Self::Value, E> {
241 Ok(JsonValue::String(value))
242 }
243
244 fn visit_none<E>(self) -> Result<Self::Value, E> {
245 Ok(JsonValue::Null)
246 }
247
248 fn visit_unit<E>(self) -> Result<Self::Value, E> {
249 Ok(JsonValue::Null)
250 }
251
252 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
253 let mut items = Vec::new();
254 while let Some(item) = seq.next_element()? {
255 items.push(item);
256 }
257 Ok(JsonValue::Array(items))
258 }
259
260 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
261 let mut fields = BTreeMap::new();
262 while let Some((key, value)) = map.next_entry::<String, JsonValue>()? {
263 fields.insert(key, value);
264 }
265 Ok(JsonValue::Object(fields))
266 }
267}