miniserde/json/
object.rs

1use crate::de::{Deserialize, Map, Visitor};
2use crate::error::Result;
3use crate::json::{drop, Value};
4use crate::ser::{self, Fragment, Serialize};
5use alloc::borrow::{Cow, ToOwned};
6use alloc::boxed::Box;
7use alloc::collections::{btree_map, BTreeMap};
8use alloc::string::String;
9use core::fmt::{self, Debug};
10use core::mem::{self, ManuallyDrop};
11use core::ops::{Deref, DerefMut};
12use core::ptr;
13use core::str;
14
15/// A `BTreeMap<String, Value>` with a non-recursive drop impl.
16#[derive(Clone, Default)]
17pub struct Object {
18    inner: BTreeMap<String, Value>,
19}
20
21impl Drop for Object {
22    fn drop(&mut self) {
23        for (_, child) in mem::take(&mut self.inner) {
24            drop::safely(child);
25        }
26    }
27}
28
29fn take(object: Object) -> BTreeMap<String, Value> {
30    let object = ManuallyDrop::new(object);
31    unsafe { ptr::read(&object.inner) }
32}
33
34impl Object {
35    pub fn new() -> Self {
36        Object {
37            inner: BTreeMap::new(),
38        }
39    }
40}
41
42impl Deref for Object {
43    type Target = BTreeMap<String, Value>;
44
45    fn deref(&self) -> &Self::Target {
46        &self.inner
47    }
48}
49
50impl DerefMut for Object {
51    fn deref_mut(&mut self) -> &mut Self::Target {
52        &mut self.inner
53    }
54}
55
56impl IntoIterator for Object {
57    type Item = (String, Value);
58    type IntoIter = <BTreeMap<String, Value> as IntoIterator>::IntoIter;
59
60    fn into_iter(self) -> Self::IntoIter {
61        take(self).into_iter()
62    }
63}
64
65impl<'a> IntoIterator for &'a Object {
66    type Item = (&'a String, &'a Value);
67    type IntoIter = <&'a BTreeMap<String, Value> as IntoIterator>::IntoIter;
68
69    fn into_iter(self) -> Self::IntoIter {
70        self.iter()
71    }
72}
73
74impl<'a> IntoIterator for &'a mut Object {
75    type Item = (&'a String, &'a mut Value);
76    type IntoIter = <&'a mut BTreeMap<String, Value> as IntoIterator>::IntoIter;
77
78    fn into_iter(self) -> Self::IntoIter {
79        self.iter_mut()
80    }
81}
82
83impl FromIterator<(String, Value)> for Object {
84    fn from_iter<I>(iter: I) -> Self
85    where
86        I: IntoIterator<Item = (String, Value)>,
87    {
88        Object {
89            inner: BTreeMap::from_iter(iter),
90        }
91    }
92}
93
94impl Debug for Object {
95    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
96        formatter.write_str("Object ")?;
97        formatter.debug_map().entries(self).finish()
98    }
99}
100
101impl Serialize for Object {
102    fn begin(&self) -> Fragment {
103        struct ObjectIter<'a>(btree_map::Iter<'a, String, Value>);
104
105        impl<'a> ser::Map for ObjectIter<'a> {
106            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
107                let (k, v) = self.0.next()?;
108                Some((Cow::Borrowed(k), v as &dyn Serialize))
109            }
110        }
111
112        Fragment::Map(Box::new(ObjectIter(self.iter())))
113    }
114}
115
116impl Deserialize for Object {
117    fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
118        make_place!(Place);
119
120        impl Visitor for Place<Object> {
121            fn map(&mut self) -> Result<Box<dyn Map + '_>> {
122                Ok(Box::new(ObjectBuilder {
123                    out: &mut self.out,
124                    object: Object::new(),
125                    key: None,
126                    value: None,
127                }))
128            }
129        }
130
131        struct ObjectBuilder<'a> {
132            out: &'a mut Option<Object>,
133            object: Object,
134            key: Option<String>,
135            value: Option<Value>,
136        }
137
138        impl<'a> ObjectBuilder<'a> {
139            fn shift(&mut self) {
140                if let (Some(k), Some(v)) = (self.key.take(), self.value.take()) {
141                    self.object.insert(k, v);
142                }
143            }
144        }
145
146        impl<'a> Map for ObjectBuilder<'a> {
147            fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
148                self.shift();
149                self.key = Some(k.to_owned());
150                Ok(Deserialize::begin(&mut self.value))
151            }
152
153            fn finish(&mut self) -> Result<()> {
154                self.shift();
155                *self.out = Some(mem::replace(&mut self.object, Object::new()));
156                Ok(())
157            }
158        }
159
160        Place::new(out)
161    }
162}