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>]);
10pub struct Keys<'tape, 'input>(&'tape [Node<'input>]);
11pub struct Values<'tape, 'input>(&'tape [Node<'input>]);
12
13impl<'tape, 'input> Object<'tape, 'input> {
15 #[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 #[must_use]
44 pub fn iter<'i>(&'i self) -> Iter<'tape, 'input> {
45 Iter(&self.0[1..])
46 }
47
48 #[must_use]
50 pub fn keys<'i>(&'i self) -> Keys<'tape, 'input> {
51 Keys(&self.0[1..])
52 }
53
54 #[must_use]
56 pub fn values<'i>(&'i self) -> Values<'tape, 'input> {
57 Values(&self.0[1..])
58 }
59
60 #[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 #[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}