Skip to main content

simd_json/value/tape/
object.rs

1use std::{borrow::Borrow, hash::Hash};
2
3use super::Value;
4use crate::Node;
5
6/// Wrapper around the tape that allows interacting with it via a `Object`-like API.
7pub struct Object<'tape, 'input>(pub(super) &'tape [Node<'input>]);
8
9/// Iterator over the key-value pairs of a tape `Object`
10pub struct Iter<'tape, 'input>(&'tape [Node<'input>]);
11/// Iterator over the keys of a tape `Object`
12pub struct Keys<'tape, 'input>(&'tape [Node<'input>]);
13/// Iterator over the values of a tape `Object`
14pub struct Values<'tape, 'input>(&'tape [Node<'input>]);
15
16//value_trait::Object for
17impl<'tape, 'input> Object<'tape, 'input> {
18    /// Gets a ref to a value based on a key, returns `None` if the
19    /// current Value isn't an Object or doesn't contain the key
20    /// it was asked for.
21    #[must_use]
22    pub fn get<Q>(&self, k: &Q) -> Option<Value<'tape, 'input>>
23    where
24        str: Borrow<Q> + Hash + Eq,
25        Q: ?Sized + Hash + Eq + Ord,
26    {
27        let &Node::Object { mut len, .. } = self.0.first()? else {
28            return None;
29        };
30        let mut idx = 1;
31        while len > 0 {
32            let s = self.0.get(idx)?.as_str()?;
33            idx += 1;
34            len -= 1;
35            let count = self.0.get(idx)?.count();
36            let s: &Q = s.borrow();
37            if s == k {
38                return Some(Value(&self.0[idx..idx + count]));
39            }
40            idx += count;
41        }
42        None
43    }
44
45    /// Iterates over the key value paris
46    #[must_use]
47    pub fn iter<'i>(&'i self) -> Iter<'tape, 'input> {
48        Iter(&self.0[1..])
49    }
50
51    /// Iterates over the keys
52    #[must_use]
53    pub fn keys<'i>(&'i self) -> Keys<'tape, 'input> {
54        Keys(&self.0[1..])
55    }
56
57    /// Iterates over the values
58    #[must_use]
59    pub fn values<'i>(&'i self) -> Values<'tape, 'input> {
60        Values(&self.0[1..])
61    }
62
63    /// Number of key/value pairs
64    #[must_use]
65    pub fn len(&self) -> usize {
66        let Some(Node::Object { len, .. }) = self.0.first() else {
67            unreachable!("invalid tape object");
68        };
69        *len
70    }
71
72    /// Returns if the object is empty
73    #[must_use]
74    pub fn is_empty(&self) -> bool {
75        self.len() == 0
76    }
77}
78
79impl<'tape, 'input> IntoIterator for &Object<'tape, 'input> {
80    type IntoIter = Iter<'tape, 'input>;
81    type Item = (&'input str, Value<'tape, 'input>);
82    fn into_iter(self) -> Self::IntoIter {
83        self.iter()
84    }
85}
86
87impl<'tape, 'input> Iterator for Iter<'tape, 'input> {
88    type Item = (&'input str, Value<'tape, 'input>);
89
90    fn next(&mut self) -> Option<Self::Item> {
91        let (k, v) = self.0.split_first()?;
92        let k = k.as_str()?;
93        let count = v.first()?.count();
94        let (head, tail) = v.split_at(count);
95        self.0 = tail;
96        Some((k, Value(head)))
97    }
98}
99
100impl<'input> Iterator for Keys<'_, 'input> {
101    type Item = &'input str;
102    fn next(&mut self) -> Option<Self::Item> {
103        let (k, v) = self.0.split_first()?;
104        let k = k.as_str()?;
105        let count = v.first()?.count();
106        let (_, tail) = v.split_at(count);
107        self.0 = tail;
108        Some(k)
109    }
110}
111
112impl<'tape, 'input> Iterator for Values<'tape, 'input> {
113    type Item = Value<'tape, 'input>;
114    fn next(&mut self) -> Option<Self::Item> {
115        let (_, v) = self.0.split_first()?;
116        let count = v.first()?.count();
117        let (head, tail) = v.split_at(count);
118        self.0 = tail;
119        Some(Value(head))
120    }
121}
122
123#[cfg(test)]
124mod test {
125    use value_trait::base::ValueAsScalar;
126
127    use crate::to_tape;
128
129    #[test]
130    fn get_ints() -> crate::Result<()> {
131        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
132        let t = to_tape(input.as_mut_slice())?;
133        let v = t.as_value();
134        let a = v.as_object().expect("is an object");
135        assert_eq!(a.get("snot").and_then(|v| v.as_u64()), Some(1));
136        assert_eq!(a.get("badger").and_then(|v| v.as_u64()), Some(2));
137        assert_eq!(a.get("cake").and_then(|v| v.as_u64()), Some(3));
138        assert_eq!(a.get("cookie").and_then(|v| v.as_u64()), Some(4));
139        assert_eq!(a.get("monster"), None);
140        Ok(())
141    }
142
143    #[test]
144    fn get_container() -> crate::Result<()> {
145        let mut input =
146            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
147        let t = to_tape(input.as_mut_slice())?;
148        let v = t.as_value();
149        let a = v.as_object().expect("is an object");
150        assert_eq!(a.get("snot").and_then(|v| v.as_u64()), Some(1));
151        let badger = a.get("badger").expect("is an array");
152        let badger = badger.as_array().expect("is an array");
153        assert_eq!(badger.get(0).and_then(|v| v.as_u64()), Some(2));
154        assert_eq!(badger.get(1).and_then(|v| v.as_f64()), Some(2.5));
155        let cake = a.get("cake").expect("is an object");
156        let cake = cake.as_object().expect("is an object");
157        assert_eq!(cake.get("frosting").and_then(|v| v.as_u64()), Some(3));
158        assert_eq!(a.get("cookie").and_then(|v| v.as_u64()), Some(4));
159        assert_eq!(a.get("monster"), None);
160        Ok(())
161    }
162    #[test]
163    fn iter_ints() -> crate::Result<()> {
164        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
165        let t = to_tape(input.as_mut_slice())?;
166        let v = t.as_value();
167        let v = v
168            .as_object()
169            .expect("is an object")
170            .iter()
171            .map(|(k, v)| (k, v.as_u64().expect("integer")))
172            .collect::<Vec<_>>();
173        assert_eq!(
174            v,
175            vec![("snot", 1), ("badger", 2), ("cake", 3), ("cookie", 4)]
176        );
177
178        Ok(())
179    }
180
181    #[test]
182    fn keys_ints() -> crate::Result<()> {
183        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
184        let t = to_tape(input.as_mut_slice())?;
185        let v = t.as_value();
186        let v = v
187            .as_object()
188            .expect("is an object")
189            .keys()
190            .collect::<Vec<_>>();
191        assert_eq!(v, vec!["snot", "badger", "cake", "cookie"]);
192
193        Ok(())
194    }
195
196    #[test]
197    fn values_ints() -> crate::Result<()> {
198        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
199        let t = to_tape(input.as_mut_slice())?;
200        let v = t.as_value();
201        let v = v
202            .as_object()
203            .expect("is an object")
204            .values()
205            .map(|v| v.as_u64().expect("integer"))
206            .collect::<Vec<_>>();
207        assert_eq!(v, vec![1, 2, 3, 4]);
208
209        Ok(())
210    }
211    #[test]
212    fn iter_container() -> crate::Result<()> {
213        let mut input =
214            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
215        let t = to_tape(input.as_mut_slice())?;
216        let v = t.as_value();
217        let v = v
218            .as_object()
219            .expect("is an object")
220            .iter()
221            .map(|(k, v)| (k, v.as_u64()))
222            .collect::<Vec<_>>();
223        assert_eq!(
224            v,
225            vec![
226                ("snot", Some(1)),
227                ("badger", None),
228                ("cake", None),
229                ("cookie", Some(4))
230            ]
231        );
232        Ok(())
233    }
234    #[test]
235    fn keys_container() -> crate::Result<()> {
236        let mut input =
237            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
238        let t = to_tape(input.as_mut_slice())?;
239        let v = t.as_value();
240        let v = v
241            .as_object()
242            .expect("is an object")
243            .keys()
244            .collect::<Vec<_>>();
245        assert_eq!(v, vec!["snot", "badger", "cake", "cookie"]);
246
247        Ok(())
248    }
249
250    #[test]
251    fn values_container() -> crate::Result<()> {
252        let mut input =
253            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
254        let t = to_tape(input.as_mut_slice())?;
255        let v = t.as_value();
256        let v = v
257            .as_object()
258            .expect("is an object")
259            .values()
260            .map(|v| v.as_u64())
261            .collect::<Vec<_>>();
262        assert_eq!(v, vec![Some(1), None, None, Some(4)]);
263
264        Ok(())
265    }
266
267    #[test]
268    fn try_get_lengths() -> crate::Result<()> {
269        // Regression test for a case where 'try_get' functions dropped the last element.
270        let mut input = br#"{"array":["a","b","c"],"object":{"x":1,"y":2,"z":3}}"#.to_vec();
271        let t = to_tape(input.as_mut_slice())?;
272        let v = t.as_value();
273
274        // get_array
275        let array = v.get_array("array").expect("is an array");
276        assert_eq!(array.len(), 3);
277        let array_items: Vec<_> = array
278            .iter()
279            .map(|v| v.as_str().expect("string").to_owned())
280            .collect();
281        assert_eq!(array_items, &["a", "b", "c"]);
282
283        // try_get_array
284        let try_array = v
285            .try_get_array("array")
286            .expect("array type")
287            .expect("is an array");
288        assert_eq!(try_array.len(), 3);
289        let try_array_items: Vec<_> = try_array
290            .iter()
291            .map(|v| v.as_str().expect("string").to_owned())
292            .collect();
293        assert_eq!(try_array_items, &["a", "b", "c"]);
294
295        // get_object
296        let object = v.get_object("object").expect("is an object");
297        assert_eq!(object.len(), 3);
298        let object_keys: Vec<_> = object.keys().collect();
299        assert_eq!(object_keys, &["x", "y", "z"]);
300
301        // try_get_object
302        let try_object = v
303            .try_get_object("object")
304            .expect("object type")
305            .expect("is an object");
306        assert_eq!(try_object.len(), 3);
307        let try_object_keys: Vec<_> = try_object.keys().collect();
308        assert_eq!(try_object_keys, &["x", "y", "z"]);
309
310        // Test with empty containers.
311        let mut input = br#"{"array":[],"object":{}}"#.to_vec();
312        let t = to_tape(input.as_mut_slice())?;
313        let v = t.as_value();
314
315        // get_array
316        let array = v.get_array("array").expect("is an array");
317        assert_eq!(array.len(), 0);
318        assert_eq!(array.iter().count(), 0);
319
320        // try_get_array
321        let try_array = v
322            .try_get_array("array")
323            .expect("array type")
324            .expect("is an array");
325        assert_eq!(try_array.len(), 0);
326        assert_eq!(try_array.iter().count(), 0);
327
328        // get_object
329        let object = v.get_object("object").expect("is an object");
330        assert_eq!(object.len(), 0);
331        assert_eq!(object.keys().count(), 0);
332
333        // try_get_object
334        let try_object = v
335            .try_get_object("object")
336            .expect("object type")
337            .expect("is an object");
338        assert_eq!(try_object.len(), 0);
339        assert_eq!(try_object.keys().count(), 0);
340
341        Ok(())
342    }
343}