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}