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