simd_json/value/lazy/
object.rs

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