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