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