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