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