imbl_value/
lib.rs

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