1pub mod error;
2pub mod parse;
3pub mod format;
4pub use bournemacro::json;
5
6#[cfg(not(feature = "preserve_order"))]
9pub type ValueMap = hashbrown::HashMap<String, Value>;
10#[cfg(feature = "preserve_order")]
13pub type ValueMap = indexmap::IndexMap<String, Value>;
14
15#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
16pub enum Number {
17 Float(f64),
18 Int(i64),
19}
20
21#[derive(Debug, Clone)]
23pub enum Value {
24 Null,
29 Boolean(bool),
38 Number(Number),
43 String(String),
59 Array(Vec<Value>),
71 Object(ValueMap),
92}
93
94impl From<bool> for Value {
95 fn from(value: bool) -> Self {
97 Value::Boolean(value)
98 }
99}
100
101impl From<f64> for Value {
102 fn from(value: f64) -> Self {
104 Value::Number(Number::Float(value))
105 }
106}
107
108impl From<String> for Value {
109 fn from(value: String) -> Self {
111 Value::String(value)
112 }
113}
114
115impl From<&str> for Value {
116 fn from(value: &str) -> Self {
118 Value::String(value.to_owned())
119 }
120}
121
122impl From<Vec<Value>> for Value {
123 fn from(value: Vec<Value>) -> Self {
125 Value::Array(value)
126 }
127}
128
129impl From<ValueMap> for Value {
130 fn from(value: ValueMap) -> Self {
132 Value::Object(value)
133 }
134}
135
136impl From<i64> for Value {
137 fn from(value: i64) -> Self {
139 Value::Number(Number::Int(value))
140 }
141}
142
143pub trait IndexOrKey {
145 fn get(self, value: &Value) -> Option<&Value>;
147 fn get_mut(self, value: &mut Value) -> Option<&mut Value>;
149 fn get_or_insert(self, value: &mut Value) -> &mut Value;
151}
152
153impl IndexOrKey for usize {
154 fn get(self, value: &Value) -> Option<&Value> {
156 let Value::Array(array) = value else {
157 return None;
158 };
159 array.get(self)
160 }
161
162 fn get_mut(self, value: &mut Value) -> Option<&mut Value> {
164 let Value::Array(array) = value else {
165 return None;
166 };
167 array.get_mut(self)
168 }
169
170 fn get_or_insert(self, _value: &mut Value) -> &mut Value {
173 let Value::Array(array) = _value else {
174 panic!("Not an array.");
175 };
176 &mut array[self]
177 }
178}
179
180impl IndexOrKey for &str {
181 fn get(self, value: &Value) -> Option<&Value> {
183 let Value::Object(object) = value else {
184 return None;
185 };
186 object.get(self)
187 }
188
189 fn get_mut(self, value: &mut Value) -> Option<&mut Value> {
191 let Value::Object(object) = value else {
192 return None;
193 };
194 object.get_mut(self)
195 }
196
197 fn get_or_insert(self, value: &mut Value) -> &mut Value {
200 if let Value::Null = value {
201 *value = Value::Object(ValueMap::new());
202 }
203 let Value::Object(object) = value else {
204 panic!("Not an object.");
205 };
206 object.entry(self.to_owned()).or_insert(Value::Null)
207 }
208}
209
210impl IndexOrKey for String {
211 fn get(self, value: &Value) -> Option<&Value> {
213 let Value::Object(object) = value else {
214 return None;
215 };
216 object.get(&self)
217 }
218
219 fn get_mut(self, value: &mut Value) -> Option<&mut Value> {
221 let Value::Object(object) = value else {
222 return None;
223 };
224 object.get_mut(&self)
225 }
226
227 fn get_or_insert(self, value: &mut Value) -> &mut Value {
230 if let Value::Null = value {
231 *value = Value::Object(ValueMap::new());
232 }
233 let Value::Object(object) = value else {
234 panic!("Not an object.");
235 };
236 object.entry(self).or_insert(Value::Null)
237 }
238}
239
240pub trait InsertKey {
242 fn insert_into(self, map: &mut ValueMap, value: Value) -> Option<Value>;
243}
244
245impl InsertKey for String {
246 fn insert_into(self, map: &mut ValueMap, value: Value) -> Option<Value> {
247 map.insert(self, value)
248 }
249}
250
251impl InsertKey for &str {
252 fn insert_into(self, map: &mut ValueMap, value: Value) -> Option<Value> {
253 map.insert(self.to_owned(), value)
254 }
255}
256
257impl Value {
258 pub fn push<T: Into<Value>>(&mut self, value: T) {
263 if let Value::Null = self {
264 *self = Value::Array(Vec::new());
265 }
266 let Value::Array(array) = self else {
267 panic!("Not an array.");
268 };
269 array.push(value.into());
270 }
271
272 pub fn insert<T: Into<Value>, K: InsertKey>(&mut self, k: K, v: T) -> Option<Value> {
277 if let Value::Null = self {
278 *self = Value::Object(ValueMap::new());
279 }
280 let Value::Object(object) = self else {
281 panic!("Not an object.");
282 };
283 k.insert_into(object, v.into())
284 }
285
286 pub fn get<I: IndexOrKey>(&self, i_k: I) -> Option<&Value> {
288 i_k.get(self)
289 }
290
291 pub fn get_mut<I: IndexOrKey>(&mut self, i_k: I) -> Option<&mut Value> {
293 i_k.get_mut(self)
294 }
295
296 pub fn len(&self) -> usize {
301 match self {
302 Value::String(string) => string.len(),
303 Value::Array(array) => array.len(),
304 Value::Object(object) => object.len(),
305 _ => 0,
306 }
307 }
308}
309
310impl<I: IndexOrKey> std::ops::Index<I> for Value {
311 type Output = Value;
312 fn index(&self, index: I) -> &Self::Output {
313 static NULL: Value = Value::Null;
314 index.get(self).unwrap_or(&NULL)
315 }
316}
317
318impl<I: IndexOrKey> std::ops::IndexMut<I> for Value {
319 fn index_mut(&mut self, index: I) -> &mut Self::Output {
320 index.get_or_insert(self)
321 }
322}
323
324pub trait ArrayExt {
325 fn push_value<T: Into<Value>>(&mut self, value: T);
326}
327
328impl ArrayExt for Vec<Value> {
329 fn push_value<T: Into<Value>>(&mut self, value: T) {
330 self.push(value.into());
331 }
332}
333
334pub trait ObjectExt {
335 fn insert_value<T: Into<Value>>(&mut self, key: String, value: T) -> Option<Value>;
336}
337
338impl ObjectExt for ValueMap {
339 fn insert_value<T: Into<Value>>(&mut self, k: String, v: T) -> Option<Value> {
340 self.insert(k, v.into())
341 }
342}
343
344#[cfg(test)]
345mod tests {
346 use core::f64;
347 use std::str::FromStr;
348
349 use super::*;
350 #[test]
351 fn parse_number_test() -> Result<(), crate::error::ParseError> {
352 let object = Value::from_str(r#"
353 {
354 "int": 9223372036854775807,
355 "float": 3.14159265358979
356 }
357 "#)?;
358 assert!(matches!(object["int"], Value::Number(Number::Int(i64::MAX))));
359 assert!(matches!(object["float"], Value::Number(Number::Float(3.14159265358979))));
360 let json_text = object.to_string();
361 assert_eq!(json_text, r#"{"int":9223372036854775807,"float":3.14159265358979}"#);
362 Ok(())
363 }
364
365 #[test]
366 fn float_nan_infinity_test() {
367 use crate as bourne;
368 let value = json!({
369 "nan": f64::NAN,
370 "infinity": f64::INFINITY,
371 "min_positive": f64::MIN_POSITIVE,
372 "min": f64::MIN,
373 "max": f64::MAX,
374 });
375 println!("{value}");
376 }
377}