Skip to main content

imbl_value/
lib.rs

1use imbl::Vector;
2use index::Index;
3use serde::{de::DeserializeOwned, Serialize};
4
5use std::{
6    cmp::Ordering,
7    fmt::{self, Debug, Display},
8    hash::{Hash, Hasher},
9    io,
10    sync::Arc,
11};
12
13pub mod de;
14mod from;
15pub mod in_order_map;
16pub mod index;
17pub mod macros;
18pub mod ser;
19
20#[cfg(feature = "arbitrary")]
21mod arbitrary;
22
23#[cfg(feature = "ts-rs")]
24mod ts_rs;
25
26pub use imbl;
27pub use in_order_map::InOMap;
28pub use serde_json::Error as ErrorSource;
29pub use serde_json::Number;
30pub use yasi::InternedString;
31
32pub const NULL: Value = Value::Null;
33
34#[derive(Debug)]
35pub enum ErrorKind {
36    Serialization,
37    Deserialization,
38}
39
40#[derive(Debug)]
41pub struct Error {
42    pub kind: ErrorKind,
43    pub source: ErrorSource,
44}
45impl std::fmt::Display for Error {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        write!(f, "{:?} Error: {}", self.kind, self.source)
48    }
49}
50impl std::error::Error for Error {}
51
52/// See the [`serde_json::value` module documentation](self) for usage examples.
53#[derive(Clone)]
54pub enum Value {
55    /// Represents a JSON null value.
56    ///
57    /// ```
58    /// use imbl_value::json;
59    ///
60    /// let v = json!(null);
61    /// ```
62    Null,
63
64    /// Represents a JSON boolean.
65    ///
66    /// ```
67    /// use imbl_value::json;
68    ///
69    /// let v = json!(true);
70    /// ```
71    Bool(bool),
72
73    /// Represents a JSON number, whether integer or floating point.
74    ///
75    /// ```
76    /// use imbl_value::json;
77    ///
78    /// let v = json!(12.5);
79    /// ```
80    Number(Number),
81
82    /// Represents a JSON string.
83    ///
84    /// ```
85    /// use imbl_value::json;
86    ///
87    /// let v = json!("a string");
88    /// ```
89    String(Arc<String>),
90
91    /// Represents a JSON array.
92    ///
93    /// ```
94    /// use imbl_value::json;
95    ///
96    /// let v = json!(["an", "array"]);
97    /// ```
98    Array(Vector<Value>),
99
100    /// Represents a JSON object.
101    ///
102    /// By default the map is backed by a BTreeMap. Enable the `preserve_order`
103    /// feature of serde_json to use IndexMap instead, which preserves
104    /// entries in the order they are inserted into the map. In particular, this
105    /// allows JSON data to be deserialized into a Value and serialized to a
106    /// string while retaining the order of map keys in the input.
107    ///
108    /// ```
109    /// use imbl_value::json;
110    ///
111    /// let v = json!({ "an": "object" });
112    /// ```
113    Object(InOMap<InternedString, Value>),
114}
115
116impl Debug for Value {
117    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
118        match self {
119            Value::Null => formatter.write_str("Null"),
120            Value::Bool(boolean) => write!(formatter, "Bool({})", boolean),
121            Value::Number(number) => Debug::fmt(number, formatter),
122            Value::String(string) => write!(formatter, "String({:?})", string),
123            Value::Array(vec) => {
124                formatter.write_str("Array ")?;
125                Debug::fmt(vec, formatter)
126            }
127            Value::Object(map) => {
128                formatter.write_str("Object ")?;
129                Debug::fmt(map, formatter)
130            }
131        }
132    }
133}
134
135impl Display for Value {
136    /// Display a JSON value as a string.
137    ///
138    /// ```
139    /// use imbl_value::json;
140    ///
141    /// let json = json!({ "city": "London", "street": "10 Downing Street" });
142    ///
143    /// // Compact format:
144    /// //
145    /// // {"city":"London","street":"10 Downing Street"}
146    /// let compact = format!("{}", json);
147    /// assert_eq!(compact,
148    ///     "{\"city\":\"London\",\"street\":\"10 Downing Street\"}");
149    ///
150    /// // Pretty format:
151    /// //
152    /// // {
153    /// //   "city": "London",
154    /// //   "street": "10 Downing Street"
155    /// // }
156    /// let pretty = format!("{:#}", json);
157    /// assert_eq!(pretty,
158    ///     "{\n  \"city\": \"London\",\n  \"street\": \"10 Downing Street\"\n}");
159    /// ```
160    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161        struct WriterFormatter<'a, 'b: 'a> {
162            inner: &'a mut fmt::Formatter<'b>,
163        }
164
165        impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
166            fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
167                // Safety: the serializer below only emits valid utf8 when using
168                // the default formatter.
169                let s = unsafe { String::from_utf8_unchecked(buf.to_owned()) };
170                self.inner.write_str(&s).map_err(io_error)?;
171                Ok(buf.len())
172            }
173
174            fn flush(&mut self) -> io::Result<()> {
175                Ok(())
176            }
177        }
178
179        fn io_error(_: fmt::Error) -> io::Error {
180            // Error value does not matter because Display impl just maps it
181            // back to fmt::Error.
182            io::Error::new(io::ErrorKind::Other, "fmt error")
183        }
184
185        let alternate = f.alternate();
186        let mut wr = WriterFormatter { inner: f };
187        if alternate {
188            // {:#}
189            serde_json::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error)
190        } else {
191            // {}
192            serde_json::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error)
193        }
194    }
195}
196
197fn parse_index(s: &str) -> Option<usize> {
198    if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) {
199        return None;
200    }
201    s.parse().ok()
202}
203
204impl Value {
205    /// Index into a JSON array or map. A string index can be used to access a
206    /// value in a map, and a usize index can be used to access an element of an
207    /// array.
208    ///
209    /// Returns `None` if the type of `self` does not match the type of the
210    /// index, for example if the index is a string and `self` is an array or a
211    /// number. Also returns `None` if the given key does not exist in the map
212    /// or the given index is not within the bounds of the array.
213    ///
214    /// ```
215    /// use imbl_value::json;
216    ///
217    /// let object = json!({ "A": 65, "B": 66, "C": 67 });
218    /// assert_eq!(*object.get("A").unwrap(), json!(65));
219    ///
220    /// let array = json!([ "A", "B", "C" ]);
221    /// assert_eq!(*array.get(2).unwrap(), json!("C"));
222    ///
223    /// assert_eq!(array.get("A"), None);
224    /// ```
225    ///
226    /// Square brackets can also be used to index into a value in a more concise
227    /// way. This returns `Value::Null` in cases where `get` would have returned
228    /// `None`.
229    ///
230    /// ```
231    /// use imbl_value::json;
232    ///
233    /// let object = json!({
234    ///     "A": ["a", "á", "à"],
235    ///     "B": ["b", "b́"],
236    ///     "C": ["c", "ć", "ć̣", "ḉ"],
237    /// });
238    /// assert_eq!(object["B"][0], json!("b"));
239    ///
240    /// assert_eq!(object["D"], json!(null));
241    /// assert_eq!(object[0]["x"]["y"]["z"], json!(null));
242    /// ```
243    pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
244        index.index_into(self)
245    }
246
247    /// Mutably index into a JSON array or map. A string index can be used to
248    /// access a value in a map, and a usize index can be used to access an
249    /// element of an array.
250    ///
251    /// Returns `None` if the type of `self` does not match the type of the
252    /// index, for example if the index is a string and `self` is an array or a
253    /// number. Also returns `None` if the given key does not exist in the map
254    /// or the given index is not within the bounds of the array.
255    ///
256    /// ```
257    /// use imbl_value::json;
258    ///
259    /// let mut object = json!({ "A": 65, "B": 66, "C": 67 });
260    /// *object.get_mut("A").unwrap() = json!(69);
261    ///
262    /// let mut array = json!([ "A", "B", "C" ]);
263    /// *array.get_mut(2).unwrap() = json!("D");
264    /// ```
265    pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
266        index.index_into_mut(self)
267    }
268
269    /// Returns true if the `Value` is an Object. Returns false otherwise.
270    ///
271    /// For any Value on which `is_object` returns true, `as_object` and
272    /// `as_object_mut` are guaranteed to return the map representation of the
273    /// object.
274    ///
275    /// ```
276    /// use imbl_value::json;
277    ///
278    /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] });
279    ///
280    /// assert!(obj.is_object());
281    /// assert!(obj["a"].is_object());
282    ///
283    /// // array, not an object
284    /// assert!(!obj["b"].is_object());
285    /// ```
286    pub fn is_object(&self) -> bool {
287        self.as_object().is_some()
288    }
289
290    /// If the `Value` is an Object, returns the associated Map. Returns None
291    /// otherwise.
292    ///
293    /// ```
294    /// use imbl_value::json;
295    ///
296    /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] });
297    ///
298    /// // The length of `{"nested": true}` is 1 entry.
299    /// assert_eq!(v["a"].as_object().unwrap().len(), 1);
300    ///
301    /// // The array `["an", "array"]` is not an object.
302    /// assert_eq!(v["b"].as_object(), None);
303    /// ```
304    pub fn as_object(&self) -> Option<&InOMap<InternedString, Value>> {
305        match self {
306            Value::Object(map) => Some(map),
307            _ => None,
308        }
309    }
310
311    /// If the `Value` is an Object, returns the associated mutable Map.
312    /// Returns None otherwise.
313    ///
314    /// ```
315    /// use imbl_value::json;
316    ///
317    /// let mut v = json!({ "a": { "nested": true } });
318    ///
319    /// v["a"].as_object_mut().unwrap().clear();
320    /// assert_eq!(v, json!({ "a": {} }));
321    /// ```
322    pub fn as_object_mut(&mut self) -> Option<&mut InOMap<InternedString, Value>> {
323        match self {
324            Value::Object(map) => Some(map),
325            _ => None,
326        }
327    }
328
329    /// Returns true if the `Value` is an Array. Returns false otherwise.
330    ///
331    /// For any Value on which `is_array` returns true, `as_array` and
332    /// `as_array_mut` are guaranteed to return the vector representing the
333    /// array.
334    ///
335    /// ```
336    /// use imbl_value::json;
337    ///
338    /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } });
339    ///
340    /// assert!(obj["a"].is_array());
341    ///
342    /// // an object, not an array
343    /// assert!(!obj["b"].is_array());
344    /// ```
345    pub fn is_array(&self) -> bool {
346        self.as_array().is_some()
347    }
348
349    /// If the `Value` is an Array, returns the associated vector. Returns None
350    /// otherwise.
351    ///
352    /// ```
353    /// use imbl_value::json;
354    ///
355    /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } });
356    ///
357    /// // The length of `["an", "array"]` is 2 elements.
358    /// assert_eq!(v["a"].as_array().unwrap().len(), 2);
359    ///
360    /// // The object `{"an": "object"}` is not an array.
361    /// assert_eq!(v["b"].as_array(), None);
362    /// ```
363    pub fn as_array(&self) -> Option<&Vector<Value>> {
364        match self {
365            Value::Array(array) => Some(array),
366            _ => None,
367        }
368    }
369
370    /// If the `Value` is an Array, returns the associated mutable vector.
371    /// Returns None otherwise.
372    ///
373    /// ```
374    /// use imbl_value::json;
375    ///
376    /// let mut v = json!({ "a": ["an", "array"] });
377    ///
378    /// v["a"].as_array_mut().unwrap().clear();
379    /// assert_eq!(v, json!({ "a": [] }));
380    /// ```
381    pub fn as_array_mut(&mut self) -> Option<&mut Vector<Value>> {
382        match self {
383            Value::Array(list) => Some(list),
384            _ => None,
385        }
386    }
387
388    /// Returns true if the `Value` is a String. Returns false otherwise.
389    ///
390    /// For any Value on which `is_string` returns true, `as_str` is guaranteed
391    /// to return the string slice.
392    ///
393    /// ```
394    /// use imbl_value::json;
395    ///
396    /// let v = json!({ "a": "some string", "b": false });
397    ///
398    /// assert!(v["a"].is_string());
399    ///
400    /// // The boolean `false` is not a string.
401    /// assert!(!v["b"].is_string());
402    /// ```
403    pub fn is_string(&self) -> bool {
404        self.as_str().is_some()
405    }
406
407    /// If the `Value` is a String, returns the associated str. Returns None
408    /// otherwise.
409    ///
410    /// ```
411    /// use imbl_value::json;
412    ///
413    /// let v = json!({ "a": "some string", "b": false });
414    ///
415    /// assert_eq!(v["a"].as_str(), Some("some string"));
416    ///
417    /// // The boolean `false` is not a string.
418    /// assert_eq!(v["b"].as_str(), None);
419    ///
420    /// // JSON values are printed in JSON representation, so strings are in quotes.
421    /// //
422    /// //    The value is: "some string"
423    /// println!("The value is: {}", v["a"]);
424    ///
425    /// // Rust strings are printed without quotes.
426    /// //
427    /// //    The value is: some string
428    /// println!("The value is: {}", v["a"].as_str().unwrap());
429    /// ```
430    pub fn as_str(&self) -> Option<&str> {
431        match self {
432            Value::String(s) => Some(s),
433            _ => None,
434        }
435    }
436
437    /// Returns true if the `Value` is a Number. Returns false otherwise.
438    ///
439    /// ```
440    /// use imbl_value::json;
441    ///
442    /// let v = json!({ "a": 1, "b": "2" });
443    ///
444    /// assert!(v["a"].is_number());
445    ///
446    /// // The string `"2"` is a string, not a number.
447    /// assert!(!v["b"].is_number());
448    /// ```
449    pub fn is_number(&self) -> bool {
450        match *self {
451            Value::Number(_) => true,
452            _ => false,
453        }
454    }
455
456    /// Returns true if the `Value` is an integer between `i64::MIN` and
457    /// `i64::MAX`.
458    ///
459    /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
460    /// return the integer value.
461    ///
462    /// ```
463    /// use imbl_value::json;
464    ///
465    /// let big = i64::max_value() as u64 + 10;
466    /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
467    ///
468    /// assert!(v["a"].is_i64());
469    ///
470    /// // Greater than i64::MAX.
471    /// assert!(!v["b"].is_i64());
472    ///
473    /// // Numbers with a decimal point are not considered integers.
474    /// assert!(!v["c"].is_i64());
475    /// ```
476    pub fn is_i64(&self) -> bool {
477        match self {
478            Value::Number(n) => n.is_i64(),
479            _ => false,
480        }
481    }
482
483    /// Returns true if the `Value` is an integer between zero and `u64::MAX`.
484    ///
485    /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
486    /// return the integer value.
487    ///
488    /// ```
489    /// use imbl_value::json;
490    ///
491    /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
492    ///
493    /// assert!(v["a"].is_u64());
494    ///
495    /// // Negative integer.
496    /// assert!(!v["b"].is_u64());
497    ///
498    /// // Numbers with a decimal point are not considered integers.
499    /// assert!(!v["c"].is_u64());
500    /// ```
501    pub fn is_u64(&self) -> bool {
502        match self {
503            Value::Number(n) => n.is_u64(),
504            _ => false,
505        }
506    }
507
508    /// Returns true if the `Value` is a number that can be represented by f64.
509    ///
510    /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to
511    /// return the floating point value.
512    ///
513    /// Currently this function returns true if and only if both `is_i64` and
514    /// `is_u64` return false but this is not a guarantee in the future.
515    ///
516    /// ```
517    /// use imbl_value::json;
518    ///
519    /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
520    ///
521    /// assert!(v["a"].is_f64());
522    ///
523    /// // Integers.
524    /// assert!(!v["b"].is_f64());
525    /// assert!(!v["c"].is_f64());
526    /// ```
527    pub fn is_f64(&self) -> bool {
528        match self {
529            Value::Number(n) => n.is_f64(),
530            _ => false,
531        }
532    }
533
534    /// If the `Value` is an integer, represent it as i64 if possible. Returns
535    /// None otherwise.
536    ///
537    /// ```
538    /// use imbl_value::json;
539    ///
540    /// let big = i64::max_value() as u64 + 10;
541    /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
542    ///
543    /// assert_eq!(v["a"].as_i64(), Some(64));
544    /// assert_eq!(v["b"].as_i64(), None);
545    /// assert_eq!(v["c"].as_i64(), None);
546    /// ```
547    pub fn as_i64(&self) -> Option<i64> {
548        match self {
549            Value::Number(n) => n.as_i64(),
550            _ => None,
551        }
552    }
553
554    /// If the `Value` is an integer, represent it as u64 if possible. Returns
555    /// None otherwise.
556    ///
557    /// ```
558    /// use imbl_value::json;
559    ///
560    /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
561    ///
562    /// assert_eq!(v["a"].as_u64(), Some(64));
563    /// assert_eq!(v["b"].as_u64(), None);
564    /// assert_eq!(v["c"].as_u64(), None);
565    /// ```
566    pub fn as_u64(&self) -> Option<u64> {
567        match self {
568            Value::Number(n) => n.as_u64(),
569            _ => None,
570        }
571    }
572
573    /// If the `Value` is a number, represent it as f64 if possible. Returns
574    /// None otherwise.
575    ///
576    /// ```
577    /// use imbl_value::json;
578    ///
579    /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
580    ///
581    /// assert_eq!(v["a"].as_f64(), Some(256.0));
582    /// assert_eq!(v["b"].as_f64(), Some(64.0));
583    /// assert_eq!(v["c"].as_f64(), Some(-64.0));
584    /// ```
585    pub fn as_f64(&self) -> Option<f64> {
586        match self {
587            Value::Number(n) => n.as_f64(),
588            _ => None,
589        }
590    }
591
592    /// Returns true if the `Value` is a Boolean. Returns false otherwise.
593    ///
594    /// For any Value on which `is_boolean` returns true, `as_bool` is
595    /// guaranteed to return the boolean value.
596    ///
597    /// ```
598    /// use imbl_value::json;
599    ///
600    /// let v = json!({ "a": false, "b": "false" });
601    ///
602    /// assert!(v["a"].is_boolean());
603    ///
604    /// // The string `"false"` is a string, not a boolean.
605    /// assert!(!v["b"].is_boolean());
606    /// ```
607    pub fn is_boolean(&self) -> bool {
608        self.as_bool().is_some()
609    }
610
611    /// If the `Value` is a Boolean, returns the associated bool. Returns None
612    /// otherwise.
613    ///
614    /// ```
615    /// use imbl_value::json;
616    ///
617    /// let v = json!({ "a": false, "b": "false" });
618    ///
619    /// assert_eq!(v["a"].as_bool(), Some(false));
620    ///
621    /// // The string `"false"` is a string, not a boolean.
622    /// assert_eq!(v["b"].as_bool(), None);
623    /// ```
624    pub fn as_bool(&self) -> Option<bool> {
625        match *self {
626            Value::Bool(b) => Some(b),
627            _ => None,
628        }
629    }
630
631    /// Returns true if the `Value` is a Null. Returns false otherwise.
632    ///
633    /// For any Value on which `is_null` returns true, `as_null` is guaranteed
634    /// to return `Some(())`.
635    ///
636    /// ```
637    /// use imbl_value::json;
638    ///
639    /// let v = json!({ "a": null, "b": false });
640    ///
641    /// assert!(v["a"].is_null());
642    ///
643    /// // The boolean `false` is not null.
644    /// assert!(!v["b"].is_null());
645    /// ```
646    pub fn is_null(&self) -> bool {
647        self.as_null().is_some()
648    }
649
650    /// If the `Value` is a Null, returns (). Returns None otherwise.
651    ///
652    /// ```
653    /// use imbl_value::json;
654    ///
655    /// let v = json!({ "a": null, "b": false });
656    ///
657    /// assert_eq!(v["a"].as_null(), Some(()));
658    ///
659    /// // The boolean `false` is not null.
660    /// assert_eq!(v["b"].as_null(), None);
661    /// ```
662    pub fn as_null(&self) -> Option<()> {
663        match *self {
664            Value::Null => Some(()),
665            _ => None,
666        }
667    }
668
669    /// Looks up a value by a JSON Pointer.
670    ///
671    /// JSON Pointer defines a string syntax for identifying a specific value
672    /// within a JavaScript Object Notation (JSON) document.
673    ///
674    /// A Pointer is a Unicode string with the reference tokens separated by `/`.
675    /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The
676    /// addressed value is returned and if there is no such value `None` is
677    /// returned.
678    ///
679    /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901).
680    ///
681    /// # Examples
682    ///
683    /// ```
684    /// use imbl_value::json;
685    ///
686    /// let data = json!({
687    ///     "x": {
688    ///         "y": ["z", "zz"]
689    ///     }
690    /// });
691    ///
692    /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz"));
693    /// assert_eq!(data.pointer("/a/b/c"), None);
694    /// ```
695    pub fn pointer(&self, pointer: &str) -> Option<&Value> {
696        if pointer.is_empty() {
697            return Some(self);
698        }
699        if !pointer.starts_with('/') {
700            return None;
701        }
702        pointer
703            .split('/')
704            .skip(1)
705            .map(|x| x.replace("~1", "/").replace("~0", "~"))
706            .map(Arc::new)
707            .try_fold(self, |target, token| match target {
708                Value::Object(map) => map.get(&**token),
709                Value::Array(list) => parse_index(&token).and_then(|x| list.get(x)),
710                _ => None,
711            })
712    }
713
714    /// Looks up a value by a JSON Pointer and returns a mutable reference to
715    /// that value.
716    ///
717    /// JSON Pointer defines a string syntax for identifying a specific value
718    /// within a JavaScript Object Notation (JSON) document.
719    ///
720    /// A Pointer is a Unicode string with the reference tokens separated by `/`.
721    /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The
722    /// addressed value is returned and if there is no such value `None` is
723    /// returned.
724    ///
725    /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901).
726    ///
727    /// # Example of Use
728    ///
729    /// ```
730    /// use imbl_value::Value;
731    ///
732    /// fn main() {
733    ///     let s = r#"{"x": 1.0, "y": 2.0}"#;
734    ///     let mut value: Value = serde_json::from_str(s).unwrap();
735    ///
736    ///     // Check value using read-only pointer
737    ///     assert_eq!(value.pointer("/x"), Some(&1.0.into()));
738    ///     // Change value with direct assignment
739    ///     *value.pointer_mut("/x").unwrap() = 1.5.into();
740    ///     // Check that new value was written
741    ///     assert_eq!(value.pointer("/x"), Some(&1.5.into()));
742    ///     // Or change the value only if it exists
743    ///     value.pointer_mut("/x").map(|v| *v = 1.5.into());
744    ///
745    ///     // "Steal" ownership of a value. Can replace with any valid Value.
746    ///     let old_x = value.pointer_mut("/x").map(Value::take).unwrap();
747    ///     assert_eq!(old_x, 1.5);
748    ///     assert_eq!(value.pointer("/x").unwrap(), &Value::Null);
749    /// }
750    /// ```
751    pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Value> {
752        if pointer.is_empty() {
753            return Some(self);
754        }
755        if !pointer.starts_with('/') {
756            return None;
757        }
758        pointer
759            .split('/')
760            .skip(1)
761            .map(|x| x.replace("~1", "/").replace("~0", "~"))
762            .map(Arc::new)
763            .try_fold(self, |target, token| match target {
764                Value::Object(map) => map.get_mut(&**token),
765                Value::Array(list) => parse_index(&token).and_then(move |x| list.get_mut(x)),
766                _ => None,
767            })
768    }
769
770    /// Takes the value out of the `Value`, leaving a `Null` in its place.
771    ///
772    /// ```
773    /// use serde_json::json;
774    ///
775    /// let mut v = json!({ "x": "y" });
776    /// assert_eq!(v["x"].take(), json!("y"));
777    /// assert_eq!(v, json!({ "x": null }));
778    /// ```
779    pub fn take(&mut self) -> Value {
780        ::std::mem::replace(self, Value::Null)
781    }
782
783    fn discriminant(&self) -> u8 {
784        match self {
785            Value::Null => 0,
786            Value::Bool(_) => 1,
787            Value::Number(_) => 2,
788            Value::String(_) => 3,
789            Value::Array(_) => 4,
790            Value::Object(_) => 5,
791        }
792    }
793
794    /// Compares whether the values refer to the same data in memory
795    ///
796    /// ```
797    /// use imbl_value::json;
798    ///
799    /// let a = json!({ "x": "y" });
800    /// let b = a.clone();
801    /// let c = json!({ "x": "y" });
802    /// assert!(a.ptr_eq(&b));
803    /// assert!(!a.ptr_eq(&c));
804    /// ```
805    pub fn ptr_eq(&self, other: &Value) -> bool {
806        match (self, other) {
807            (Self::Array(a), Self::Array(b)) => a.ptr_eq(b),
808            (Self::Object(a), Self::Object(b)) => a.ptr_eq(b),
809            (Self::String(a), Self::String(b)) => Arc::ptr_eq(a, b),
810            (a, b) => a == b, // primitive - trivial comparison
811        }
812    }
813}
814
815/// The default value is `Value::Null`.
816///
817/// This is useful for handling omitted `Value` fields when deserializing.
818///
819/// # Examples
820///
821/// ```
822/// # use serde::Deserialize;
823/// use imbl_value::Value;
824///
825/// #[derive(Deserialize)]
826/// struct Settings {
827///     level: i32,
828///     #[serde(default)]
829///     extras: Value,
830/// }
831///
832/// # fn try_main() -> Result<(), serde_json::Error> {
833/// let data = r#" { "level": 42 } "#;
834/// let s: Settings = serde_json::from_str(data)?;
835///
836/// assert_eq!(s.level, 42);
837/// assert_eq!(s.extras, Value::Null);
838/// #
839/// #     Ok(())
840/// # }
841/// #
842/// # try_main().unwrap()
843/// ```
844impl Default for Value {
845    fn default() -> Value {
846        Value::Null
847    }
848}
849
850impl PartialEq for Value {
851    fn eq(&self, other: &Self) -> bool {
852        match (self, other) {
853            (Value::Array(a), Value::Array(b)) => a.ptr_eq(b) || a == b,
854            (Value::Bool(a), Value::Bool(b)) => a == b,
855            (Value::Null, Value::Null) => true,
856            (Value::Number(a), Value::Number(b)) => a == b,
857
858            (Value::Object(a), Value::Object(b)) => a.ptr_eq(b) || a == b,
859            (Value::String(a), Value::String(b)) => Arc::ptr_eq(a, b) || a == b,
860            _ => false,
861        }
862    }
863}
864impl Eq for Value {}
865
866impl PartialOrd for Value {
867    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
868        Some(self.cmp(other))
869    }
870}
871
872impl Ord for Value {
873    fn cmp(&self, other: &Self) -> Ordering {
874        match (self, other) {
875            (Value::Null, Value::Null) => Ordering::Equal,
876            (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
877            (Value::Number(a), Value::Number(b)) => a.to_string().cmp(&b.to_string()),
878            (Value::String(a), Value::String(b)) => a.cmp(b),
879            (Value::Array(a), Value::Array(b)) => a.cmp(b),
880            (Value::Object(a), Value::Object(b)) => a.cmp(b),
881            _ => self.discriminant().cmp(&other.discriminant()),
882        }
883    }
884}
885
886impl Hash for Value {
887    fn hash<H: Hasher>(&self, state: &mut H) {
888        std::mem::discriminant(self).hash(state);
889        match self {
890            Value::Null => {}
891            Value::Bool(b) => b.hash(state),
892            Value::Number(n) => n.to_string().hash(state),
893            Value::String(s) => s.hash(state),
894            Value::Array(a) => a.hash(state),
895            Value::Object(o) => o.hash(state),
896        }
897    }
898}
899
900impl PartialEq<f64> for Value {
901    fn eq(&self, other: &f64) -> bool {
902        match self {
903            Value::Number(n) => n.as_f64() == Some(*other),
904            _ => false,
905        }
906    }
907}
908impl PartialEq<i64> for Value {
909    fn eq(&self, other: &i64) -> bool {
910        match self {
911            Value::Number(n) => n.as_i64() == Some(*other),
912            _ => false,
913        }
914    }
915}
916impl PartialEq<u64> for Value {
917    fn eq(&self, other: &u64) -> bool {
918        match self {
919            Value::Number(n) => n.as_u64() == Some(*other),
920            _ => false,
921        }
922    }
923}
924impl PartialEq<str> for Value {
925    fn eq(&self, other: &str) -> bool {
926        match self {
927            Value::String(s) => &**s == other,
928            _ => false,
929        }
930    }
931}
932
933pub fn to_value<T>(value: &T) -> Result<Value, Error>
934where
935    T: Serialize,
936{
937    value.serialize(ser::Serializer).map_err(|e| Error {
938        kind: ErrorKind::Serialization,
939        source: e,
940    })
941}
942
943pub fn from_value<T>(value: Value) -> Result<T, Error>
944where
945    T: DeserializeOwned,
946{
947    T::deserialize(value).map_err(|e| Error {
948        kind: ErrorKind::Deserialization,
949        source: e,
950    })
951}
952
953#[test]
954fn test_serialize_loop() {
955    let value = json!({
956        "a": "hello I'm a",
957        "b": 1,
958        "c": true,
959        "d": null,
960        "e": [123, "testing"],
961        "f": { "h": 'i'}
962    });
963    assert_eq!(
964        &serde_json::to_string(&value)
965        .unwrap(),
966        "{\"a\":\"hello I'm a\",\"b\":1,\"c\":true,\"d\":null,\"e\":[123,\"testing\"],\"f\":{\"h\":\"i\"}}"
967    );
968    assert_eq!(
969        value,
970        serde_json::from_str::<Value>(&serde_json::to_string(&value).unwrap()).unwrap(),
971    );
972
973    assert_eq!(value["f"]["h"].as_str().unwrap(), "i");
974}