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