1use std::{borrow::Borrow, hash::Hash};
2
3use super::Value;
4use crate::Node;
5
6pub struct Object<'tape, 'input>(pub(super) &'tape [Node<'input>]);
8
9pub struct Iter<'tape, 'input>(&'tape [Node<'input>]);
11pub struct Keys<'tape, 'input>(&'tape [Node<'input>]);
13pub struct Values<'tape, 'input>(&'tape [Node<'input>]);
15
16impl<'tape, 'input> Object<'tape, 'input> {
18 #[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 #[must_use]
47 pub fn iter<'i>(&'i self) -> Iter<'tape, 'input> {
48 Iter(&self.0[1..])
49 }
50
51 #[must_use]
53 pub fn keys<'i>(&'i self) -> Keys<'tape, 'input> {
54 Keys(&self.0[1..])
55 }
56
57 #[must_use]
59 pub fn values<'i>(&'i self) -> Values<'tape, 'input> {
60 Values(&self.0[1..])
61 }
62
63 #[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 #[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 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 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 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 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 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 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 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 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 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 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}