json_utils/json/
query_for_js_value.rs1use crate::json::JsValue;
2
3use crate::query::Path;
4use crate::query::PathComponent;
5use crate::query::Query;
6
7impl<'v> Query<'v> for JsValue {
8 type Item = Self;
9 type ItemRef = &'v Self::Item;
10
11 fn lookup<'p, P>(&'v self, path: P) -> Option<Self::ItemRef>
12 where
13 P: Path<'p>,
14 {
15 lookup(self, path.path())
16 }
17
18 fn take<'p, P>(self, path: P) -> (Option<Self>, Option<Self::Item>)
19 where
20 P: Path<'p>,
21 {
22 take(self, path.path())
23 }
24
25 fn insert<'p, P>(&mut self, path: P, insertee: Self::Item) -> Result<(), Self::Item>
26 where
27 P: Path<'p>,
28 {
29 insert(self, path.path(), insertee)
30 }
31}
32
33fn lookup<'v, 'p, P: PathComponent<'p>, I: Iterator<Item = P>>(
34 v: &'v JsValue,
35 mut components: I,
36) -> Option<&'v JsValue> {
37 if let Some(component) = components.next() {
38 match *v {
39 JsValue::Object(ref fields) => fields
40 .get(component.as_str_slice())
41 .and_then(move |child| lookup(child, components)),
42 _ => None,
43 }
44 } else {
45 Some(v)
46 }
47}
48
49fn take<'p, P: PathComponent<'p>, I: Iterator<Item = P>>(
50 v: JsValue,
51 mut components: I,
52) -> (Option<JsValue>, Option<JsValue>) {
53 if let Some(component) = components.next() {
54 match v {
55 JsValue::Object(mut fields) => {
56 let child_key = component.as_str_slice();
57 if let Some(child) = fields.remove(child_key) {
58 let (child_opt, taken_opt) = take(child, components);
59
60 if let Some(child) = child_opt {
61 fields.insert(child_key.to_owned(), child);
62 };
63
64 if fields.is_empty() {
65 (None, taken_opt)
66 } else {
67 (Some(JsValue::Object(fields)), taken_opt)
68 }
69 } else {
70 (Some(JsValue::Object(fields)), None)
71 }
72 }
73 as_is => (Some(as_is), None),
74 }
75 } else {
76 (None, Some(v))
77 }
78}
79
80fn insert<'p, P: PathComponent<'p>, I: Iterator<Item = P>>(
81 v: &mut JsValue,
82 mut components: I,
83 insertee: JsValue,
84) -> Result<(), JsValue> {
85 if let Some(component) = components.next() {
86 match *v {
87 JsValue::Object(ref mut fields) => {
88 let child_key = component.as_str_slice();
89
90 if let Some(ref mut child) = fields.get_mut(child_key) {
91 insert(child, components, insertee)
92 } else {
93 let mut child = json!({});
94
95 let () = insert(&mut child, components, insertee)
96 .expect("Failed to insert into a newly created ObjectNode");
97
98 fields.insert(child_key.to_owned(), child);
99 Ok(())
100 }
101 }
102 _ => Err(insertee),
103 }
104 } else {
105 *v = insertee;
106 Ok(())
107 }
108}