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