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}