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