1use std::{
2 borrow::{Borrow, Cow},
3 hash::Hash,
4};
5
6use super::Value;
7use crate::{borrowed, tape};
8
9pub enum Object<'borrow, 'tape, 'input> {
11 Tape(tape::Object<'tape, 'input>),
13 Value(&'borrow borrowed::Object<'input>),
15}
16pub enum Iter<'borrow, 'tape, 'input> {
18 Tape(tape::object::Iter<'tape, 'input>),
20 Value(halfbrown::Iter<'borrow, crate::cow::Cow<'input, str>, borrowed::Value<'input>>),
22}
23
24pub enum Keys<'borrow, 'tape, 'input> {
26 Tape(tape::object::Keys<'tape, 'input>),
28 Value(halfbrown::Keys<'borrow, crate::cow::Cow<'input, str>, borrowed::Value<'input>>),
30}
31pub enum Values<'borrow, 'tape, 'input> {
33 Tape(tape::object::Values<'tape, 'input>),
35 Value(halfbrown::Values<'borrow, crate::cow::Cow<'input, str>, borrowed::Value<'input>>),
37}
38
39impl<'tape, 'input> Object<'_, 'tape, 'input> {
41 #[must_use]
45 pub fn get<'a, Q>(&'a self, k: &Q) -> Option<Value<'a, 'tape, 'input>>
46 where
47 str: Borrow<Q>,
48 for<'b> crate::cow::Cow<'b, str>: Borrow<Q>,
49 Q: ?Sized + Hash + Eq + Ord,
50 {
51 match self {
52 Object::Tape(t) => t.get(k).map(Value::Tape),
53 Object::Value(v) => v.get(k).map(Cow::Borrowed).map(Value::Value),
54 }
55 }
56
57 #[allow(clippy::pedantic)] #[must_use]
60 pub fn iter<'i>(&'i self) -> Iter<'i, 'tape, 'input> {
61 match self {
62 Object::Tape(t) => Iter::Tape(t.iter()),
63 Object::Value(v) => Iter::Value(v.iter()),
64 }
65 }
66
67 #[must_use]
69 pub fn keys<'i>(&'i self) -> Keys<'i, 'tape, 'input> {
70 match self {
71 Object::Tape(t) => Keys::Tape(t.keys()),
72 Object::Value(v) => Keys::Value(v.keys()),
73 }
74 }
75
76 #[must_use]
78 pub fn values<'i>(&'i self) -> Values<'i, 'tape, 'input> {
79 match self {
80 Object::Tape(t) => Values::Tape(t.values()),
81 Object::Value(v) => Values::Value(v.values()),
82 }
83 }
84
85 #[must_use]
87 pub fn len(&self) -> usize {
88 match self {
89 Object::Tape(t) => t.len(),
90 Object::Value(v) => v.len(),
91 }
92 }
93
94 #[must_use]
96 pub fn is_empty(&self) -> bool {
97 self.len() == 0
98 }
99}
100
101impl<'borrow, 'tape, 'input> Iterator for Iter<'borrow, 'tape, 'input> {
110 type Item = (&'borrow str, Value<'borrow, 'tape, 'input>);
111
112 fn next(&mut self) -> Option<Self::Item> {
113 match self {
114 Iter::Tape(t) => t.next().map(|(k, v)| (k, Value::Tape(v))),
115 Iter::Value(v) => v
116 .next()
117 .map(|(k, v)| (k.as_ref(), Value::Value(Cow::Borrowed(v)))),
118 }
119 }
120}
121
122impl<'borrow> Iterator for Keys<'borrow, '_, '_> {
123 type Item = &'borrow str;
124 fn next(&mut self) -> Option<Self::Item> {
125 match self {
126 Keys::Tape(t) => t.next(),
127 Keys::Value(v) => v.next().map(std::convert::AsRef::as_ref),
128 }
129 }
130}
131
132impl<'borrow, 'tape, 'input> Iterator for Values<'borrow, 'tape, 'input> {
133 type Item = Value<'borrow, 'tape, 'input>;
134 fn next(&mut self) -> Option<Self::Item> {
135 match self {
136 Values::Tape(t) => t.next().map(Value::Tape),
137 Values::Value(v) => v.next().map(|v| Value::Value(Cow::Borrowed(v))),
138 }
139 }
140}
141
142#[cfg(test)]
143mod test {
144 use value_trait::base::ValueAsScalar;
145
146 use crate::to_tape;
147
148 #[test]
149 fn get_ints() -> crate::Result<()> {
150 let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
151 let t = to_tape(input.as_mut_slice())?;
152 let v = t.as_value();
153 let a = v.as_object().expect("is an object");
154 assert_eq!(a.get("snot").and_then(|v| v.as_u64()), Some(1));
155 assert_eq!(a.get("badger").and_then(|v| v.as_u64()), Some(2));
156 assert_eq!(a.get("cake").and_then(|v| v.as_u64()), Some(3));
157 assert_eq!(a.get("cookie").and_then(|v| v.as_u64()), Some(4));
158 assert_eq!(a.get("monster"), None);
159 Ok(())
160 }
161
162 #[test]
163 fn get_container() -> crate::Result<()> {
164 let mut input =
165 br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
166 let t = to_tape(input.as_mut_slice())?;
167 let v = t.as_value();
168 let a = v.as_object().expect("is an object");
169 assert_eq!(a.get("snot").and_then(|v| v.as_u64()), Some(1));
170 let badger = a.get("badger").expect("is an array");
171 let badger = badger.as_array().expect("is an array");
172 assert_eq!(badger.get(0).and_then(|v| v.as_u64()), Some(2));
173 assert_eq!(badger.get(1).and_then(|v| v.as_f64()), Some(2.5));
174 let cake = a.get("cake").expect("is an object");
175 let cake = cake.as_object().expect("is an object");
176 assert_eq!(cake.get("frosting").and_then(|v| v.as_u64()), Some(3));
177 assert_eq!(a.get("cookie").and_then(|v| v.as_u64()), Some(4));
178 assert_eq!(a.get("monster"), None);
179 Ok(())
180 }
181 #[test]
182 fn iter_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 .iter()
190 .map(|(k, v)| (k, v.as_u64().expect("integer")))
191 .collect::<Vec<_>>();
192 assert_eq!(
193 v,
194 vec![("snot", 1), ("badger", 2), ("cake", 3), ("cookie", 4)]
195 );
196
197 Ok(())
198 }
199
200 #[test]
201 fn keys_ints() -> crate::Result<()> {
202 let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
203 let t = to_tape(input.as_mut_slice())?;
204 let v = t.as_value();
205 let v = v
206 .as_object()
207 .expect("is an object")
208 .keys()
209 .collect::<Vec<_>>();
210 assert_eq!(v, vec!["snot", "badger", "cake", "cookie"]);
211
212 Ok(())
213 }
214
215 #[test]
216 fn values_ints() -> crate::Result<()> {
217 let mut input = br#"{"snot": 1, "badger":2, "cake":3, "cookie":4}"#.to_vec();
218 let t = to_tape(input.as_mut_slice())?;
219 let v = t.as_value();
220 let v = v
221 .as_object()
222 .expect("is an object")
223 .values()
224 .map(|v| v.as_u64().expect("integer"))
225 .collect::<Vec<_>>();
226 assert_eq!(v, vec![1, 2, 3, 4]);
227
228 Ok(())
229 }
230 #[test]
231 fn iter_container() -> crate::Result<()> {
232 let mut input =
233 br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
234 let t = to_tape(input.as_mut_slice())?;
235 let v = t.as_value();
236 let v = v
237 .as_object()
238 .expect("is an object")
239 .iter()
240 .map(|(k, v)| (k, v.as_u64()))
241 .collect::<Vec<_>>();
242 assert_eq!(
243 v,
244 vec![
245 ("snot", Some(1)),
246 ("badger", None),
247 ("cake", None),
248 ("cookie", Some(4))
249 ]
250 );
251 Ok(())
252 }
253 #[test]
254 fn keys_container() -> crate::Result<()> {
255 let mut input =
256 br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
257 let t = to_tape(input.as_mut_slice())?;
258 let v = t.as_value();
259 let v = v
260 .as_object()
261 .expect("is an object")
262 .keys()
263 .collect::<Vec<_>>();
264 assert_eq!(v, vec!["snot", "badger", "cake", "cookie"]);
265
266 Ok(())
267 }
268
269 #[test]
270 fn values_container() -> crate::Result<()> {
271 let mut input =
272 br#"{"snot": 1, "badger":[2, 2.5], "cake":{"frosting": 3}, "cookie":4}"#.to_vec();
273 let t = to_tape(input.as_mut_slice())?;
274 let v = t.as_value();
275 let v = v
276 .as_object()
277 .expect("is an object")
278 .values()
279 .map(|v| v.as_u64())
280 .collect::<Vec<_>>();
281 assert_eq!(v, vec![Some(1), None, None, Some(4)]);
282
283 Ok(())
284 }
285}