sonic_rs/value/object.rs
1//! Represents a parsed JSON object.
2use std::{iter::FusedIterator, marker::PhantomData, slice};
3
4use faststr::FastStr;
5use ref_cast::RefCast;
6
7use super::{
8 node::{ValueMut, ValueRefInner},
9 value_trait::JsonValueTrait,
10};
11use crate::{serde::tri, util::reborrow::DormantMutRef, value::node::Value};
12
13/// Represents the JSON object. The inner implement is a key-value array. Its order is as same as
14/// origin JSON.
15///
16/// # Examples
17/// ```
18/// use sonic_rs::{from_str, Object};
19///
20/// let mut obj: Object = from_str(r#"{"a": 1, "b": true, "c": null}"#).unwrap();
21///
22/// assert_eq!(obj["a"], 1);
23/// assert_eq!(obj.insert(&"d", "e"), None);
24/// assert_eq!(obj["d"], "e");
25/// assert_eq!(obj.len(), 4);
26/// ```
27///
28/// # Warning
29/// The key in `Object` is not sorted and the `get` operation is O(n). And `Object` is allowed to
30/// have duplicated keys.
31///
32/// # Examples
33/// ```
34/// use sonic_rs::{from_str, Object};
35///
36/// let obj: Object = from_str(r#"{"a": 1, "a": true, "a": null}"#).unwrap();
37///
38/// assert_eq!(obj["a"], 1);
39/// assert_eq!(obj.len(), 3); // allow duplicated keys
40/// ```
41/// If you care about that, recommend to use `HashMap` or `BTreeMap` instead. The parse performance
42/// is slower than `Object`.
43#[derive(Debug, Clone, RefCast)]
44#[repr(transparent)]
45pub struct Object(pub(crate) Value);
46
47impl Default for Object {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53impl PartialEq for Object {
54 #[inline]
55 fn eq(&self, other: &Self) -> bool {
56 if self.len() != other.len() {
57 return false;
58 }
59 // because we allow duplicated keys in object, so we need to compare by `get`
60 self.iter().all(|(k, _)| other.get(&k) == self.get(&k))
61 }
62}
63
64#[doc(hidden)]
65pub type Pair = (Value, Value);
66
67impl Object {
68 /// Returns the inner `Value`.
69 #[inline]
70 pub fn into_value(self) -> Value {
71 self.0
72 }
73
74 /// Create a new empty object.
75 ///
76 /// # Example
77 /// ```
78 /// use sonic_rs::{from_str, json, object, prelude::*, Object};
79 ///
80 /// let mut obj: Object = from_str("{}").unwrap();
81 /// obj.insert(&"arr", object! {});
82 /// obj.insert(&"a", 1);
83 /// obj.insert(&"arr2", Object::new());
84 /// obj["a"] = json!(123);
85 /// obj["arr2"] = json!("hello world");
86 ///
87 /// assert_eq!(obj["a"], 123);
88 /// assert_eq!(obj["arr2"], "hello world");
89 /// ```
90 #[inline]
91 pub fn new() -> Object {
92 Object(Value::new_object())
93 }
94
95 /// Create a new empty object with capacity.
96 #[inline]
97 pub fn with_capacity(capacity: usize) -> Self {
98 Object(Value::new_object_with(capacity))
99 }
100
101 /// Clear the object, make it as empty but keep the allocated memory.
102 ///
103 /// # Examples
104 ///
105 /// ```
106 /// use sonic_rs::{json, object};
107 ///
108 /// let mut obj = object! {"a": 1, "b": true, "c": null};
109 /// obj.clear();
110 /// assert!(obj.is_empty());
111 /// #[cfg(not(feature = "sort_keys"))]
112 /// assert!(obj.capacity() >= 3);
113 /// ```
114 #[inline]
115 pub fn clear(&mut self) {
116 self.0.clear();
117 }
118
119 /// Returns the capacity of the object.
120 #[inline]
121 pub fn capacity(&self) -> usize {
122 self.0.capacity()
123 }
124
125 /// Returns a reference to the value corresponding to the key.
126 ///
127 /// The key may be [`AsRef<str>`].
128 ///
129 /// # Examples
130 ///
131 /// ```
132 /// use sonic_rs::{json, object};
133 ///
134 /// let mut obj = object! {"a": 1, "b": true, "c": null};
135 /// obj.insert(&"d", "e");
136 /// assert_eq!(obj.get(&"d").unwrap(), "e");
137 /// assert_eq!(obj.get(&"f"), None);
138 /// assert_eq!(obj.get(&"a").unwrap(), 1);
139 /// ```
140 #[inline]
141 pub fn get<Q: AsRef<str>>(&self, key: &Q) -> Option<&Value> {
142 self.0.get_key(key.as_ref())
143 }
144
145 /// Returns `true` if the map contains a value for the specified key.
146 ///
147 /// The key may be [`AsRef<str>`].
148 ///
149 /// # Examples
150 ///
151 /// ```
152 /// use sonic_rs::object;
153 ///
154 /// let mut obj = object! {"a": 1, "b": true, "c": null};
155 /// obj.insert(&"d", "e");
156 /// assert_eq!(obj.contains_key(&"d"), true);
157 /// assert_eq!(obj.contains_key(&"a"), true);
158 /// assert_eq!(obj.contains_key(&"e"), false);
159 /// ```
160 #[inline]
161 pub fn contains_key<Q: AsRef<str>>(&self, key: &Q) -> bool {
162 self.get(key).is_some()
163 }
164
165 /// Returns a mutable reference to the value corresponding to the key.
166 ///
167 /// The key may be [`AsRef<str>`].
168 ///
169 /// # Examples
170 ///
171 /// ```
172 /// use sonic_rs::object;
173 ///
174 /// let mut obj = object! {"a": 1, "b": true, "c": null};
175 /// obj.insert(&"d", "e");
176 ///
177 /// *(obj.get_mut(&"d").unwrap()) = "f".into();
178 /// assert_eq!(obj.contains_key(&"d"), true);
179 /// assert_eq!(obj["d"], "f");
180 /// ```
181 #[inline]
182 pub fn get_mut<Q: AsRef<str>>(&mut self, key: &Q) -> Option<&mut Value> {
183 self.0.get_key_mut(key.as_ref())
184 }
185
186 /// Returns the key-value pair corresponding to the supplied key.
187 ///
188 /// The key may be [`AsRef<str>`].
189 ///
190 /// # Examples
191 ///
192 /// ```
193 /// use sonic_rs::{object, Value};
194 ///
195 /// let mut obj = object! {"a": 1, "b": true, "c": null};
196 /// obj.insert(&"d", "e");
197 ///
198 /// assert_eq!(obj.get_key_value(&"d").unwrap(), ("d", &Value::from("e")));
199 /// assert_eq!(obj.get_key_value(&"a").unwrap(), ("a", &Value::from(1)));
200 /// assert_eq!(obj.get_key_value(&"e"), None);
201 /// ```
202 #[inline]
203 pub fn get_key_value<Q: AsRef<str>>(&self, key: &Q) -> Option<(&str, &Value)> {
204 self.0.get_key_value(key.as_ref())
205 }
206
207 /// Inserts a key-value pair into the object. The `Value` is converted from `V`.
208 ///
209 /// The key may be [`AsRef<str>`].
210 ///
211 /// If the object did not have this key present, [`None`] is returned.
212 ///
213 /// If the object did have this key present, the value is updated, and the old
214 /// value is returned. The key is not updated, though; this matters for
215 /// types that can be `==` without being identical. See the [module-level
216 /// documentation] for more.
217 ///
218 /// # Examples
219 ///
220 /// ```
221 /// use sonic_rs::{json, object, Value};
222 ///
223 /// let mut obj = object! {"a": 1, "b": true, "c": null};
224 /// assert_eq!(obj.len(), 3);
225 /// assert_eq!(obj.insert(&"d", "e"), None);
226 /// assert_eq!(obj.len(), 4);
227 /// assert_eq!(obj["d"], "e");
228 /// assert_eq!(obj.insert(&"d", "f").unwrap(), "e");
229 /// assert_eq!(obj["d"], "f");
230 /// assert_eq!(obj.len(), 4);
231 /// assert_eq!(obj.insert(&"d", json!("h")).unwrap(), "f");
232 /// assert_eq!(obj["d"], "h");
233 /// assert_eq!(obj.insert(&"i", Value::from("j")), None);
234 /// assert_eq!(obj.len(), 5);
235 /// ```
236 #[inline]
237 pub fn insert<K: AsRef<str> + ?Sized, V: Into<Value>>(
238 &mut self,
239 key: &K,
240 value: V,
241 ) -> Option<Value> {
242 match self.entry(key) {
243 Entry::Occupied(mut entry) => Some(entry.insert(value)),
244 Entry::Vacant(entry) => {
245 entry.insert(value);
246 None
247 }
248 }
249 }
250
251 /// Removes a key from the object, returning the value at the key if the key
252 /// was previously in the object.
253 ///
254 /// The key may be [`AsRef<str>`].
255 ///
256 /// # Examples
257 ///
258 /// ```
259 /// use sonic_rs::object;
260 ///
261 /// let mut obj = object! {"a": 1, "b": true, "c": null};
262 /// assert_eq!(obj.remove(&"d"), None);
263 /// assert_eq!(obj.remove(&"a").unwrap(), 1);
264 /// ```
265 #[inline]
266 pub fn remove<Q: AsRef<str>>(&mut self, key: &Q) -> Option<Value> {
267 self.0.remove_key(key.as_ref())
268 }
269
270 /// Removes a key from the object, returning the stored key and value if the
271 /// key was previously in the obj.
272 ///
273 /// The key may be [`AsRef<str>`].
274 ///
275 /// # Examples
276 ///
277 /// ```
278 /// use sonic_rs::object;
279 ///
280 /// let mut obj = object! {"a": 1, "b": true, "c": null};
281 /// assert_eq!(obj.remove_entry(&"d"), None);
282 /// let (key, val) = obj.remove_entry(&"a").unwrap();
283 /// assert_eq!(key, "a");
284 /// assert_eq!(val, 1);
285 /// ```
286 #[inline]
287 pub fn remove_entry<'k, Q: AsRef<str>>(&mut self, key: &'k Q) -> Option<(&'k str, Value)> {
288 self.0.remove_key(key.as_ref()).map(|v| (key.as_ref(), v))
289 }
290
291 /// Returns the number of key-value paris in the object.
292 #[inline]
293 pub fn len(&self) -> usize {
294 self.0.as_obj_len()
295 }
296
297 /// Returns true if the object contains no key-value pairs.
298 #[inline]
299 pub fn is_empty(&self) -> bool {
300 self.len() == 0
301 }
302
303 /// Returns an immutable iterator over the key-value pairs of the object.
304 ///
305 /// # Examples
306 /// ```
307 /// use sonic_rs::object;
308 ///
309 /// let obj = object! {"a": 1, "b": true, "c": null};
310 ///
311 /// for (key, value) in obj.iter() {
312 /// println!("{}: {}", key, value);
313 /// }
314 /// ```
315 #[inline]
316 pub fn iter(&self) -> Iter<'_> {
317 Iter(match self.0.as_ref2() {
318 ValueRefInner::Object(obj) => IterInner::Slice(obj.iter()),
319 ValueRefInner::EmptyObject => IterInner::Slice([].iter()),
320 ValueRefInner::ObjectOwned(obj) => IterInner::Map(obj.iter()),
321 _ => unreachable!("should not used in non-object"),
322 })
323 }
324
325 /// Returns an mutable iterator over the key-value pairs of the object.
326 ///
327 /// # Examples
328 /// ```
329 /// use sonic_rs::{object, Value};
330 ///
331 /// let mut obj = object! {"a": 1, "b": true, "c": null};
332 ///
333 /// for (key, value) in obj.iter_mut() {
334 /// *value = Value::from(key);
335 /// }
336 ///
337 /// assert_eq!(obj["a"], "a");
338 /// assert_eq!(obj["b"], "b");
339 /// assert_eq!(obj["c"], "c");
340 /// ```
341 #[inline]
342 pub fn iter_mut(&mut self) -> IterMut<'_> {
343 if let ValueMut::Object(obj) = self.0.as_mut() {
344 IterMut(obj.iter_mut())
345 } else {
346 unreachable!("should not used in array")
347 }
348 }
349
350 /// Gets the given key's corresponding entry in the object for in-place manipulation.
351 ///
352 /// # Examples
353 ///
354 /// ```
355 /// use sonic_rs::{object, Value};
356 ///
357 /// let mut obj = object! {};
358 ///
359 /// for i in 0..10 {
360 /// obj.entry(&i.to_string()).or_insert(1);
361 /// }
362 ///
363 /// for i in 0..10 {
364 /// obj.entry(&i.to_string())
365 /// .and_modify(|v| *v = Value::from(i + 1));
366 /// }
367 ///
368 /// assert_eq!(obj[&"1"], 2);
369 /// assert_eq!(obj[&"2"], 3);
370 /// assert_eq!(obj[&"3"], 4);
371 /// assert_eq!(obj.get(&"10"), None);
372 /// ```
373 #[inline]
374 pub fn entry<'a, Q: AsRef<str> + ?Sized>(&'a mut self, key: &'a Q) -> Entry<'a> {
375 let (obj, dormant_obj) = DormantMutRef::new(self);
376 match obj.0.get_key_mut(key.as_ref()) {
377 None => {
378 // check flat
379 let key = Value::copy_str(key.as_ref());
380 Entry::Vacant(VacantEntry {
381 key,
382 dormant_obj,
383 _marker: PhantomData,
384 })
385 }
386 Some(handle) => Entry::Occupied(OccupiedEntry::new(handle, key.as_ref(), dormant_obj)),
387 }
388 }
389
390 /// Retains only the elements specified by the predicate.
391 ///
392 /// In other words, remove all pairs `(k, v)` for which `f(&k, &mut v)` returns `false`.
393 /// The elements are visited in unsorted (and unspecified) order.
394 ///
395 /// # Examples
396 ///
397 /// ```
398 /// use sonic_rs::object;
399 ///
400 /// let mut obj = object! {"a": 1, "b": true, "c": null};
401 /// obj.retain(|key, _| key == "a");
402 /// assert_eq!(obj.len(), 1);
403 /// assert_eq!(obj["a"], 1);
404 /// ```
405 #[inline]
406 pub fn retain<F>(&mut self, mut f: F)
407 where
408 F: FnMut(&str, &mut Value) -> bool,
409 {
410 if let ValueMut::Object(s) = self.0.as_mut() {
411 s.retain(|k, v| f(k.as_str(), v));
412 } else {
413 unreachable!("should not used in array")
414 }
415 }
416
417 /// Moves all elements from other into self, leaving other empty.
418 ///
419 /// # Examples
420 ///
421 /// ```
422 /// use sonic_rs::{json, object};
423 ///
424 /// let mut a = object! {};
425 /// let mut b = object! {"a": null, "b": 1};
426 /// a.append(&mut b);
427 ///
428 /// assert_eq!(a, object! {"a": null, "b": 1});
429 /// assert!(b.is_empty());
430 /// ```
431 #[inline]
432 pub fn append(&mut self, other: &mut Self) {
433 if let ValueMut::Object(o) = self.0.as_mut() {
434 #[cfg(not(feature = "sort_keys"))]
435 if let ValueMut::Object(oo) = other.0.as_mut() {
436 o.reserve(oo.len());
437 o.extend(oo.drain());
438 } else {
439 unreachable!("should not used in object")
440 }
441
442 #[cfg(feature = "sort_keys")]
443 if let ValueMut::Object(oo) = other.0.as_mut() {
444 o.append(oo);
445 } else {
446 unreachable!("should not used in object")
447 }
448 } else {
449 unreachable!("should not used in object")
450 }
451 }
452
453 /// Reserves capacity for at least additional more elements to be inserted in the given.
454 ///
455 /// # Examples
456 /// ```
457 /// use sonic_rs::object;
458 /// let mut obj = object! {};
459 /// #[cfg(not(feature = "sort_keys"))]
460 /// {
461 /// obj.reserve(1);
462 /// assert!(obj.capacity() >= 1);
463 /// }
464 ///
465 /// #[cfg(not(feature = "sort_keys"))]
466 /// {
467 /// obj.reserve(10);
468 /// assert!(obj.capacity() >= 10);
469 /// }
470 /// ```
471 #[inline]
472 pub fn reserve(&mut self, additional: usize) {
473 self.0.reserve::<Pair>(additional);
474 }
475}
476
477/// A view into a single occupied location in a `Object`.
478pub struct OccupiedEntry<'a> {
479 handle: &'a mut Value,
480 key: &'a str,
481 dormant_obj: DormantMutRef<'a, Object>,
482 _marker: PhantomData<&'a mut Pair>,
483}
484
485impl<'a> OccupiedEntry<'a> {
486 /// Gets a reference to the value in the entry.
487 ///
488 /// # Examples
489 ///
490 /// ```
491 /// use sonic_rs::{object, value::object::Entry, Value};
492 ///
493 /// let mut obj = object! {"a": 1, "b": true, "c": null};
494 ///
495 /// if let Entry::Occupied(entry) = obj.entry(&"a") {
496 /// assert_eq!(entry.get(), 1);
497 /// }
498 ///
499 /// if let Entry::Occupied(entry) = obj.entry(&"b") {
500 /// assert_eq!(entry.get(), true);
501 /// }
502 /// ```
503 #[inline]
504 pub fn get(&self) -> &Value {
505 self.handle
506 }
507
508 /// Gets a mutable reference to the value in the entry.
509 ///
510 /// # Examples
511 ///
512 /// ```
513 /// use sonic_rs::{object, value::object::Entry, Value};
514 ///
515 /// let mut obj = object! {"a": 1, "b": true, "c": null};
516 /// obj.insert(&"a", Value::from("hello"));
517 ///
518 /// if let Entry::Occupied(mut entry) = obj.entry(&"a") {
519 /// assert_eq!(entry.get_mut(), &Value::from("hello"));
520 /// }
521 ///
522 /// if let Entry::Occupied(mut entry) = obj.entry(&"b") {
523 /// assert_eq!(entry.get_mut(), &true);
524 /// }
525 /// ```
526 #[inline]
527 pub fn get_mut(&mut self) -> &mut Value {
528 self.handle
529 }
530
531 /// Converts the entry into a mutable reference to its value.
532 ///
533 /// # Examples
534 ///
535 /// ```
536 /// use sonic_rs::{object, value::object::Entry, Value};
537 ///
538 /// let mut obj = object! {"a": 1, "b": true, "c": null};
539 /// obj.insert(&"a", Value::from("hello"));
540 ///
541 /// if let Entry::Occupied(mut entry) = obj.entry(&"a") {
542 /// let vref = entry.into_mut();
543 /// assert_eq!(vref, &mut Value::from("hello"));
544 /// *vref = Value::from("world");
545 /// }
546 ///
547 /// assert_eq!(obj["a"], "world");
548 /// ```
549 #[inline]
550 pub fn into_mut(self) -> &'a mut Value {
551 self.handle
552 }
553
554 /// Sets the value of the entry, and returns the entry's old value.
555 ///
556 /// # Examples
557 ///
558 /// ```
559 /// use sonic_rs::{object, value::object::Entry};
560 ///
561 /// let mut obj = object! {"a": 1, "b": true, "c": null};
562 ///
563 /// if let Entry::Occupied(mut entry) = obj.entry(&"a") {
564 /// assert_eq!(entry.insert("hello"), 1);
565 /// }
566 /// if let Entry::Occupied(mut entry) = obj.entry(&"a") {
567 /// assert_eq!(entry.insert("world"), "hello");
568 /// }
569 /// ```
570 #[inline]
571 pub fn insert<T: Into<Value>>(&mut self, val: T) -> Value {
572 let old = self.handle.take();
573 *self.handle = val.into();
574 old
575 }
576
577 /// Takes the value out of the entry, and returns it.
578 ///
579 /// # Examples
580 /// ```
581 /// use sonic_rs::{object, value::object::Entry, Value};
582 ///
583 /// let mut obj = object! {"a": 1, "b": true, "c": null};
584 ///
585 /// if let Entry::Occupied(mut entry) = obj.entry(&"a") {
586 /// assert_eq!(entry.remove(), 1);
587 /// }
588 ///
589 /// if let Entry::Occupied(mut entry) = obj.entry(&"b") {
590 /// assert_eq!(entry.remove(), true);
591 /// }
592 ///
593 /// if let Entry::Occupied(mut entry) = obj.entry(&"c") {
594 /// assert_eq!(entry.remove(), Value::default());
595 /// }
596 /// assert!(obj.is_empty());
597 /// ```
598 #[inline]
599 pub fn remove(mut self) -> Value {
600 let obj = unsafe { self.dormant_obj.reborrow() };
601 obj.0.remove_key(self.key).unwrap()
602 }
603
604 #[inline]
605 pub(crate) fn new(
606 handle: &'a mut Value,
607 key: &'a str,
608 dormant_obj: DormantMutRef<'a, Object>,
609 ) -> Self {
610 Self {
611 handle,
612 key,
613 dormant_obj,
614 _marker: PhantomData,
615 }
616 }
617}
618
619/// A view into a vacant entry in a `Object`.
620pub struct VacantEntry<'a> {
621 pub(super) key: Value,
622 pub(super) dormant_obj: DormantMutRef<'a, Object>,
623 pub(super) _marker: PhantomData<&'a mut Pair>,
624}
625
626impl<'a> VacantEntry<'a> {
627 /// Insert a value into the vacant entry and return a mutable reference to it.
628 ///
629 /// # Examples
630 ///
631 /// ```
632 /// use sonic_rs::{json, object, value::object::Entry};
633 ///
634 /// let mut obj = object! {};
635 ///
636 /// if let Entry::Vacant(entry) = obj.entry(&"hello") {
637 /// assert_eq!(entry.insert(1), &1);
638 /// }
639 ///
640 /// if let Entry::Vacant(entry) = obj.entry(&"world") {
641 /// assert_eq!(entry.insert(json!("woo").clone()), "woo");
642 /// }
643 ///
644 /// assert_eq!(obj.get(&"hello").unwrap(), 1);
645 /// assert_eq!(obj.get(&"world").unwrap(), "woo");
646 /// ```
647 pub fn insert<T: Into<Value>>(self, val: T) -> &'a mut Value {
648 let obj = unsafe { self.dormant_obj.awaken() };
649 #[cfg(not(feature = "sort_keys"))]
650 obj.reserve(1);
651 let val = obj.0.insert(self.key.as_str().unwrap(), val.into());
652 val
653 }
654
655 /// Get the key of the vacant entry.
656 pub fn key(&self) -> &str {
657 self.key.as_str().unwrap()
658 }
659}
660
661/// A view into a single entry in a map, which may either be vacant or occupied.
662pub enum Entry<'a> {
663 /// A vacant Entry.
664 Vacant(VacantEntry<'a>),
665 /// An occupied Entry.
666 Occupied(OccupiedEntry<'a>),
667}
668
669impl<'a> Entry<'a> {
670 /// Ensures a value is in the entry by inserting the default if empty,
671 /// Example:
672 /// ```rust
673 /// use sonic_rs::object;
674 ///
675 /// let mut obj = object! {};
676 /// obj.entry(&"hello").or_insert(1);
677 /// assert_eq!(obj.get(&"hello").unwrap(), 1);
678 ///
679 /// obj.entry(&"hello").or_insert(2);
680 /// assert_eq!(obj.get(&"hello").unwrap(), 1);
681 /// ```
682 #[inline]
683 pub fn or_insert<T: Into<Value>>(self, default: T) -> &'a mut Value {
684 match self {
685 Entry::Occupied(entry) => entry.into_mut(),
686 Entry::Vacant(entry) => entry.insert(default),
687 }
688 }
689
690 /// Ensures a value is in the entry by inserting the result of the default function if empty,
691 /// Example:
692 /// ```rust
693 /// use sonic_rs::Object;
694 /// let mut obj = Object::new();
695 /// obj.entry(&"hello").or_insert_with(|| 1.into());
696 /// assert_eq!(obj.get(&"hello").unwrap(), 1);
697 ///
698 /// obj.entry(&"hello").or_insert_with(|| 2.into());
699 /// assert_eq!(obj.get(&"hello").unwrap(), 1);
700 /// ```
701 #[inline]
702 pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value {
703 match self {
704 Entry::Occupied(entry) => entry.into_mut(),
705 Entry::Vacant(entry) => entry.insert(default()),
706 }
707 }
708
709 /// Return the key of the entry.
710 #[inline]
711 pub fn key(&self) -> &str {
712 match self {
713 Entry::Occupied(entry) => entry.handle.as_str().unwrap(),
714 Entry::Vacant(entry) => entry.key(),
715 }
716 }
717
718 /// Provides in-place mutable access to an occupied entry before any potential inserts into the
719 /// object.
720 ///
721 /// # Examples
722 ///
723 /// ```
724 /// use sonic_rs::{object, value::object::Entry};
725 ///
726 /// let mut obj = object! {"a": 0, "b": true, "c": null};
727 /// obj.entry(&"a").and_modify(|v| *v = 2.into());
728 /// assert_eq!(obj.get(&"a").unwrap(), 2);
729 ///
730 /// obj.entry(&"a")
731 /// .and_modify(|v| *v = 2.into())
732 /// .and_modify(|v| *v = 3.into());
733 /// assert_eq!(obj.get(&"a").unwrap(), 3);
734 ///
735 /// obj.entry(&"d").and_modify(|v| *v = 3.into());
736 /// assert_eq!(obj.get(&"d"), None);
737 ///
738 /// obj.entry(&"d").and_modify(|v| *v = 3.into()).or_insert(4);
739 /// assert_eq!(obj.get(&"d").unwrap(), 4);
740 /// ```
741 #[inline]
742 pub fn and_modify<F: FnOnce(&mut Value)>(self, f: F) -> Self {
743 match self {
744 Entry::Occupied(entry) => {
745 f(entry.handle);
746 Entry::Occupied(entry)
747 }
748 Entry::Vacant(entry) => Entry::Vacant(entry),
749 }
750 }
751
752 /// Ensures a value is in the entry by inserting the default value if empty, and returns a
753 /// mutable reference to the value in the entry. # Examples
754 ///
755 /// ```
756 /// use sonic_rs::{object, value::object::Entry, Value};
757 ///
758 /// let mut obj = object! {"c": null};
759 /// assert_eq!(obj.entry(&"a").or_default(), &Value::default());
760 /// assert_eq!(obj.entry(&"d").or_default(), &Value::default());
761 /// ```
762 #[inline]
763 pub fn or_default(self) -> &'a mut Value {
764 match self {
765 Entry::Occupied(entry) => entry.into_mut(),
766 Entry::Vacant(entry) => entry.insert(Value::default()),
767 }
768 }
769
770 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
771 /// This method allows for generating key-derived values for insertion by providing the default
772 /// function a reference to the key that was moved during the `.entry(key)` method call.
773 ///
774 /// The reference to the moved key is provided so that cloning or copying the key is
775 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
776 ///
777 /// # Examples
778 ///
779 /// ```
780 /// use sonic_rs::{object, Value};
781 ///
782 /// let mut obj = object! {"c": null};
783 ///
784 /// obj.entry(&"a")
785 /// .or_insert_with_key(|key| Value::from(key.len()));
786 /// assert_eq!(obj.get(&"a").unwrap(), 1);
787 ///
788 /// obj.entry(&"b").or_insert_with_key(|key| Value::from(key));
789 /// assert_eq!(obj.get(&"b").unwrap(), "b");
790 /// ```
791 #[inline]
792 pub fn or_insert_with_key<F>(self, default: F) -> &'a mut Value
793 where
794 F: FnOnce(&str) -> Value,
795 {
796 match self {
797 Entry::Occupied(entry) => entry.into_mut(),
798 Entry::Vacant(entry) => {
799 let value = default(entry.key());
800 entry.insert(value)
801 }
802 }
803 }
804}
805
806/// An iterator over the entries of a `Object`.
807enum IterInner<'a> {
808 #[cfg(not(feature = "sort_keys"))]
809 Map(std::collections::hash_map::Iter<'a, FastStr, Value>),
810 #[cfg(feature = "sort_keys")]
811 Map(std::collections::btree_map::Iter<'a, FastStr, Value>),
812 Slice(slice::Iter<'a, (Value, Value)>),
813}
814pub struct Iter<'a>(IterInner<'a>);
815
816impl<'a> Iterator for Iter<'a> {
817 type Item = (&'a str, &'a Value);
818
819 #[inline]
820 fn next(&mut self) -> Option<Self::Item> {
821 match &mut self.0 {
822 IterInner::Map(iter) => iter.next().map(|(k, v)| (k.as_str(), v)),
823 IterInner::Slice(iter) => iter.next().map(|(k, v)| (k.as_str().unwrap(), v)),
824 }
825 }
826}
827
828impl<'a> ExactSizeIterator for Iter<'a> {
829 #[inline]
830 fn len(&self) -> usize {
831 match &self.0 {
832 IterInner::Map(iter) => iter.len(),
833 IterInner::Slice(iter) => iter.len(),
834 }
835 }
836}
837
838impl<'a> FusedIterator for Iter<'a> {}
839
840/// A mutable iterator over the entries of a `Object`.
841pub struct IterMut<'a>(
842 #[cfg(not(feature = "sort_keys"))] std::collections::hash_map::IterMut<'a, FastStr, Value>,
843 #[cfg(feature = "sort_keys")] std::collections::btree_map::IterMut<'a, FastStr, Value>,
844);
845
846impl<'a> Iterator for IterMut<'a> {
847 type Item = (&'a str, &'a mut Value);
848
849 #[inline]
850 fn next(&mut self) -> Option<Self::Item> {
851 self.0.next().map(|(k, v)| (k.as_str(), v))
852 }
853}
854
855impl<'a> ExactSizeIterator for IterMut<'a> {
856 #[inline]
857 fn len(&self) -> usize {
858 self.0.len()
859 }
860}
861
862impl<'a> FusedIterator for IterMut<'a> {}
863/// An iterator over the keys of a `Object`.
864pub struct Keys<'a>(Iter<'a>);
865
866impl<'a> Iterator for Keys<'a> {
867 type Item = &'a str;
868
869 #[inline]
870 fn next(&mut self) -> Option<Self::Item> {
871 self.0.next().map(|(k, _)| k)
872 }
873}
874
875impl<'a> ExactSizeIterator for Keys<'a> {
876 #[inline]
877 fn len(&self) -> usize {
878 self.0.len()
879 }
880}
881
882impl<'a> FusedIterator for Keys<'a> {}
883
884macro_rules! impl_value_iter {
885 (($name:ident $($generics:tt)*): $item:ty) => {
886 impl $($generics)* Iterator for $name $($generics)* {
887 type Item = $item;
888
889 #[inline]
890 fn next(&mut self) -> Option<Self::Item> {
891 self.0.next().map(|(_, v)| v)
892 }
893 }
894
895 impl $($generics)* ExactSizeIterator for $name $($generics)* {
896 #[inline]
897 fn len(&self) -> usize {
898 self.0.len()
899 }
900 }
901
902 impl $($generics)* FusedIterator for $name $($generics)* {}
903 };
904}
905
906/// An iterator over the values of a `Object`.
907pub struct Values<'a>(Iter<'a>);
908impl_value_iter!((Values<'a>): &'a Value);
909
910/// A mutable iterator over the values of a `Object`.
911pub struct ValuesMut<'a>(IterMut<'a>);
912impl_value_iter!((ValuesMut<'a>): &'a mut Value);
913
914impl<'a> IntoIterator for &'a Object {
915 type Item = (&'a str, &'a Value);
916 type IntoIter = Iter<'a>;
917
918 #[inline]
919 fn into_iter(self) -> Self::IntoIter {
920 self.iter()
921 }
922}
923
924impl<'a> IntoIterator for &'a mut Object {
925 type Item = (&'a str, &'a mut Value);
926 type IntoIter = IterMut<'a>;
927
928 #[inline]
929 fn into_iter(self) -> Self::IntoIter {
930 self.iter_mut()
931 }
932}
933
934impl<'a, Q: AsRef<str> + ?Sized> std::ops::Index<&'a Q> for Object {
935 type Output = Value;
936
937 #[inline]
938 fn index(&self, index: &'a Q) -> &Self::Output {
939 self.get(&index.as_ref()).unwrap()
940 }
941}
942
943impl<'a, Q: AsRef<str> + ?Sized> std::ops::IndexMut<&'a Q> for Object {
944 #[inline]
945 fn index_mut(&mut self, index: &'a Q) -> &mut Self::Output {
946 if let ValueMut::Object(o) = self.0.as_mut() {
947 o.entry(FastStr::new(index.as_ref()))
948 .or_insert(Value::default())
949 } else {
950 unreachable!("should not used in object")
951 }
952 }
953}
954
955impl serde::ser::Serialize for Object {
956 #[inline]
957 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
958 where
959 S: serde::ser::Serializer,
960 {
961 use serde::ser::SerializeMap;
962 let mut map = tri!(serializer.serialize_map(Some(self.len())));
963 for (k, v) in self {
964 tri!(map.serialize_entry(k, v));
965 }
966 map.end()
967 }
968}
969
970impl<'de> serde::de::Deserialize<'de> for Object {
971 #[inline]
972 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
973 where
974 D: serde::de::Deserializer<'de>,
975 {
976 // deserialize to value at first
977 let value: Value =
978 deserializer.deserialize_newtype_struct(super::de::TOKEN, super::de::ValueVisitor)?;
979 if value.is_object() {
980 Ok(Object(value))
981 } else {
982 Err(serde::de::Error::invalid_type(
983 serde::de::Unexpected::Other("not a object"),
984 &"object",
985 ))
986 }
987 }
988}
989
990#[cfg(test)]
991mod test {
992 use super::*;
993 use crate::{from_str, to_string, Array, JsonValueMutTrait};
994
995 #[test]
996 fn test_object_serde() {
997 let json = r#"{"a": 1, "b": true, "c": null}"#;
998 let obj: Object = from_str(json).unwrap();
999 assert_eq!(obj, object! {"a": 1, "b": true, "c": null});
1000 let json = to_string(&obj).unwrap();
1001 assert_eq!(json, r#"{"a":1,"b":true,"c":null}"#);
1002 }
1003
1004 #[test]
1005 fn test_value_object() {
1006 let mut val = crate::from_str::<Value>(r#"{"a": 123, "b": "hello"}"#).unwrap();
1007 let obj = val.as_object_mut().unwrap();
1008
1009 for i in 0..3 {
1010 // push static node
1011 let new_node = Value::new_u64(i);
1012 obj["c"] = new_node;
1013 assert_eq!(obj["c"], i);
1014
1015 // push node with new allocator
1016 let mut new_node = Array::default();
1017 new_node.push(Value::new_u64(i));
1018 obj.insert(&"d", new_node);
1019 assert_eq!(obj["d"][0], i);
1020
1021 // push node with self allocator
1022 let mut new_node = Array::new();
1023 new_node.push(Value::new_u64(i));
1024 obj.insert(&"e", new_node);
1025 assert_eq!(obj["e"][0], i);
1026 }
1027
1028 for (i, v) in obj.iter_mut().0.enumerate() {
1029 *(v.1) = Value::from(&i.to_string());
1030 }
1031
1032 for (i, v) in obj.iter().enumerate() {
1033 assert_eq!(v.1, &Value::from(&i.to_string()));
1034 }
1035 }
1036}