Skip to main content

miniserde_miku/json/
object.rs

1use crate::json::{drop, Value};
2use crate::private;
3use crate::ser::{self, Fragment, Serialize};
4use alloc::borrow::Cow;
5use alloc::boxed::Box;
6use alloc::collections::{btree_map, BTreeMap};
7use alloc::string::String;
8use core::iter::FromIterator;
9use core::mem::{self, ManuallyDrop};
10use core::ops::{Deref, DerefMut};
11use core::ptr;
12use core::str;
13
14/// A `BTreeMap<String, Value>` with a non-recursive drop impl.
15#[derive(Clone, Debug, Default)]
16pub struct Object {
17    inner: BTreeMap<String, Value>,
18}
19
20impl Drop for Object {
21    fn drop(&mut self) {
22        for (_, child) in mem::replace(&mut self.inner, BTreeMap::new()) {
23            drop::safely(child);
24        }
25    }
26}
27
28fn take(object: Object) -> BTreeMap<String, Value> {
29    let object = ManuallyDrop::new(object);
30    unsafe { ptr::read(&object.inner) }
31}
32
33impl Object {
34    pub fn new() -> Self {
35        Object {
36            inner: BTreeMap::new(),
37        }
38    }
39}
40
41impl Deref for Object {
42    type Target = BTreeMap<String, Value>;
43
44    fn deref(&self) -> &Self::Target {
45        &self.inner
46    }
47}
48
49impl DerefMut for Object {
50    fn deref_mut(&mut self) -> &mut Self::Target {
51        &mut self.inner
52    }
53}
54
55impl IntoIterator for Object {
56    type Item = (String, Value);
57    type IntoIter = <BTreeMap<String, Value> as IntoIterator>::IntoIter;
58
59    fn into_iter(self) -> Self::IntoIter {
60        take(self).into_iter()
61    }
62}
63
64impl<'a> IntoIterator for &'a Object {
65    type Item = (&'a String, &'a Value);
66    type IntoIter = <&'a BTreeMap<String, Value> as IntoIterator>::IntoIter;
67
68    fn into_iter(self) -> Self::IntoIter {
69        self.iter()
70    }
71}
72
73impl<'a> IntoIterator for &'a mut Object {
74    type Item = (&'a String, &'a mut Value);
75    type IntoIter = <&'a mut BTreeMap<String, Value> as IntoIterator>::IntoIter;
76
77    fn into_iter(self) -> Self::IntoIter {
78        self.iter_mut()
79    }
80}
81
82impl FromIterator<(String, Value)> for Object {
83    fn from_iter<I>(iter: I) -> Self
84    where
85        I: IntoIterator<Item = (String, Value)>,
86    {
87        Object {
88            inner: BTreeMap::from_iter(iter),
89        }
90    }
91}
92
93impl private {
94    pub fn stream_object(object: &Object) -> Fragment {
95        struct ObjectIter<'a>(btree_map::Iter<'a, String, Value>);
96
97        impl<'a> ser::Map for ObjectIter<'a> {
98            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
99                let (k, v) = self.0.next()?;
100                Some((Cow::Borrowed(k), v as &dyn Serialize))
101            }
102        }
103
104        Fragment::Map(Box::new(ObjectIter(object.iter())))
105    }
106}