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