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.
7
8pub struct Object<'tape, 'input>(pub(super) &'tape [Node<'input>]);
9
10pub struct Iter<'tape, 'input>(&'tape [Node<'input>]);
11pub struct Keys<'tape, 'input>(&'tape [Node<'input>]);
12pub struct Values<'tape, 'input>(&'tape [Node<'input>]);
13
14//value_trait::Object for
15impl<'tape, 'input> Object<'tape, 'input> {
16    /// Gets a ref to a value based on a key, returns `None` if the
17    /// current Value isn't an Object or doesn't contain the key
18    /// it was asked for.
19    #[must_use]
20    pub fn get<Q>(&self, k: &Q) -> Option<Value<'tape, 'input>>
21    where
22        str: Borrow<Q> + Hash + Eq,
23        Q: ?Sized + Hash + Eq + Ord,
24    {
25        let Node::Object { mut len, .. } = self.0.first()? else {
26            return None;
27        };
28        let mut idx = 1;
29        while len > 0 {
30            let s = self.0.get(idx)?.as_str()?;
31            idx += 1;
32            len -= 1;
33            let count = self.0.get(idx)?.count();
34            let s: &Q = s.borrow();
35            if s == k {
36                return Some(Value(&self.0[idx..idx + count]));
37            }
38            idx += count;
39        }
40        None
41    }
42
43    /// Iterates over the key value paris
44    #[must_use]
45    pub fn iter<'i>(&'i self) -> Iter<'tape, 'input> {
46        Iter(&self.0[1..])
47    }
48
49    /// Iterates over the keys
50    #[must_use]
51    pub fn keys<'i>(&'i self) -> Keys<'tape, 'input> {
52        Keys(&self.0[1..])
53    }
54
55    /// Iterates over the values
56    #[must_use]
57    pub fn values<'i>(&'i self) -> Values<'tape, 'input> {
58        Values(&self.0[1..])
59    }
60
61    /// Number of key/value pairs
62    #[must_use]
63    pub fn len(&self) -> usize {
64        let Some(Node::Object { len, .. }) = self.0.first() else {
65            unreachable!("invalid tape object");
66        };
67        *len
68    }
69
70    /// Returns if the object is empty
71    #[must_use]
72    pub fn is_empty(&self) -> bool {
73        self.len() == 0
74    }
75}
76
77impl<'tape, 'input> IntoIterator for &Object<'tape, 'input> {
78    type IntoIter = Iter<'tape, 'input>;
79    type Item = (&'input str, Value<'tape, 'input>);
80    fn into_iter(self) -> Self::IntoIter {
81        self.iter()
82    }
83}
84
85impl<'tape, 'input> Iterator for Iter<'tape, 'input> {
86    type Item = (&'input str, Value<'tape, 'input>);
87
88    fn next(&mut self) -> Option<Self::Item> {
89        let (k, v) = self.0.split_first()?;
90        let k = k.as_str()?;
91        let count = v.first()?.count();
92        let (head, tail) = v.split_at(count);
93        self.0 = tail;
94        Some((k, Value(head)))
95    }
96}
97
98impl<'tape, 'input> Iterator for Keys<'tape, 'input> {
99    type Item = &'input str;
100    fn next(&mut self) -> Option<Self::Item> {
101        let (k, v) = self.0.split_first()?;
102        let k = k.as_str()?;
103        let count = v.first()?.count();
104        let (_, tail) = v.split_at(count);
105        self.0 = tail;
106        Some(k)
107    }
108}
109
110impl<'tape, 'input> Iterator for Values<'tape, 'input> {
111    type Item = Value<'tape, 'input>;
112    fn next(&mut self) -> Option<Self::Item> {
113        let (_, v) = self.0.split_first()?;
114        let count = v.first()?.count();
115        let (head, tail) = v.split_at(count);
116        self.0 = tail;
117        Some(Value(head))
118    }
119}
120
121#[cfg(test)]
122mod test {
123    use value_trait::base::ValueAsScalar;
124
125    use crate::to_tape;
126
127    #[test]
128    fn get_ints() -> crate::Result<()> {
129        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
130        let t = to_tape(input.as_mut_slice())?;
131        let v = t.as_value();
132        let a = v.as_object().expect("is an object");
133        assert_eq!(a.get("snot").and_then(|v| v.as_u64()), Some(1));
134        assert_eq!(a.get("badger").and_then(|v| v.as_u64()), Some(2));
135        assert_eq!(a.get("cake").and_then(|v| v.as_u64()), Some(3));
136        assert_eq!(a.get("cookie").and_then(|v| v.as_u64()), Some(4));
137        assert_eq!(a.get("monster"), None);
138        Ok(())
139    }
140
141    #[test]
142    fn get_container() -> crate::Result<()> {
143        let mut input =
144            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
145        let t = to_tape(input.as_mut_slice())?;
146        let v = t.as_value();
147        let a = v.as_object().expect("is an object");
148        assert_eq!(a.get("snot").and_then(|v| v.as_u64()), Some(1));
149        let badger = a.get("badger").expect("is an array");
150        let badger = badger.as_array().expect("is an array");
151        assert_eq!(badger.get(0).and_then(|v| v.as_u64()), Some(2));
152        assert_eq!(badger.get(1).and_then(|v| v.as_f64()), Some(2.5));
153        let cake = a.get("cake").expect("is an object");
154        let cake = cake.as_object().expect("is an object");
155        assert_eq!(cake.get("frosting").and_then(|v| v.as_u64()), Some(3));
156        assert_eq!(a.get("cookie").and_then(|v| v.as_u64()), Some(4));
157        assert_eq!(a.get("monster"), None);
158        Ok(())
159    }
160    #[test]
161    fn iter_ints() -> crate::Result<()> {
162        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
163        let t = to_tape(input.as_mut_slice())?;
164        let v = t.as_value();
165        let v = v
166            .as_object()
167            .expect("is an object")
168            .iter()
169            .map(|(k, v)| (k, v.as_u64().expect("integer")))
170            .collect::<Vec<_>>();
171        assert_eq!(
172            v,
173            vec![("snot", 1), ("badger", 2), ("cake", 3), ("cookie", 4)]
174        );
175
176        Ok(())
177    }
178
179    #[test]
180    fn keys_ints() -> crate::Result<()> {
181        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
182        let t = to_tape(input.as_mut_slice())?;
183        let v = t.as_value();
184        let v = v
185            .as_object()
186            .expect("is an object")
187            .keys()
188            .collect::<Vec<_>>();
189        assert_eq!(v, vec!["snot", "badger", "cake", "cookie"]);
190
191        Ok(())
192    }
193
194    #[test]
195    fn values_ints() -> crate::Result<()> {
196        let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
197        let t = to_tape(input.as_mut_slice())?;
198        let v = t.as_value();
199        let v = v
200            .as_object()
201            .expect("is an object")
202            .values()
203            .map(|v| v.as_u64().expect("integer"))
204            .collect::<Vec<_>>();
205        assert_eq!(v, vec![1, 2, 3, 4]);
206
207        Ok(())
208    }
209    #[test]
210    fn iter_container() -> crate::Result<()> {
211        let mut input =
212            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
213        let t = to_tape(input.as_mut_slice())?;
214        let v = t.as_value();
215        let v = v
216            .as_object()
217            .expect("is an object")
218            .iter()
219            .map(|(k, v)| (k, v.as_u64()))
220            .collect::<Vec<_>>();
221        assert_eq!(
222            v,
223            vec![
224                ("snot", Some(1)),
225                ("badger", None),
226                ("cake", None),
227                ("cookie", Some(4))
228            ]
229        );
230        Ok(())
231    }
232    #[test]
233    fn keys_container() -> crate::Result<()> {
234        let mut input =
235            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
236        let t = to_tape(input.as_mut_slice())?;
237        let v = t.as_value();
238        let v = v
239            .as_object()
240            .expect("is an object")
241            .keys()
242            .collect::<Vec<_>>();
243        assert_eq!(v, vec!["snot", "badger", "cake", "cookie"]);
244
245        Ok(())
246    }
247
248    #[test]
249    fn values_container() -> crate::Result<()> {
250        let mut input =
251            br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
252        let t = to_tape(input.as_mut_slice())?;
253        let v = t.as_value();
254        let v = v
255            .as_object()
256            .expect("is an object")
257            .values()
258            .map(|v| v.as_u64())
259            .collect::<Vec<_>>();
260        assert_eq!(v, vec![Some(1), None, None, Some(4)]);
261
262        Ok(())
263    }
264}