json_utils/schema/
query_for_schema_node.rs1use std::fmt;
2
3use crate::query::Path;
4use crate::query::PathComponent;
5use crate::query::Query;
6
7use super::SchemaNode;
8use super::ValidNode;
9
10#[derive(Debug, Clone, PartialEq)]
11pub struct QueryNode<T: fmt::Debug + Clone + PartialEq> {
12 pub schema: T,
13 pub is_required: bool,
14}
15
16impl<'v> Query<'v> for SchemaNode {
17 type Item = QueryNode<SchemaNode>;
18 type ItemRef = QueryNode<&'v SchemaNode>;
19
20 fn lookup<'p, P>(&'v self, path: P) -> Option<Self::ItemRef>
21 where
22 P: Path<'p>,
23 {
24 lookup(self, true, path.path())
25 }
26
27 fn take<'p, P>(self, path: P) -> (Option<Self>, Option<Self::Item>)
28 where
29 P: Path<'p>,
30 {
31 take(self, true, path.path())
32 }
33
34 fn insert<'p, P>(&mut self, path: P, insertee: Self::Item) -> Result<(), Self::Item>
35 where
36 P: Path<'p>,
37 {
38 insert(self, path.path(), insertee)
39 }
40}
41
42fn lookup<'v, 'p, P: PathComponent<'p>, I: Iterator<Item = P>>(
43 v: &'v SchemaNode,
44 is_required: bool,
45 mut components: I,
46) -> Option<QueryNode<&'v SchemaNode>> {
47 if let Some(component) = components.next() {
48 if let SchemaNode::ValidNode(ValidNode::ObjectNode(ref object_node)) = *v {
49 let child_key = component.as_str_slice();
50 let child_is_required = object_node.required.contains(child_key);
51 object_node
52 .properties
53 .get(child_key)
54 .and_then(move |ref child| lookup(child, child_is_required, components))
55 } else {
56 None
57 }
58 } else {
59 let qn = QueryNode {
60 is_required,
61 schema: v,
62 };
63 Some(qn)
64 }
65}
66
67fn take<'v, 'p, P: PathComponent<'p>, I: Iterator<Item = P>>(
68 v: SchemaNode,
69 is_required: bool,
70 mut components: I,
71) -> (Option<SchemaNode>, Option<QueryNode<SchemaNode>>) {
72 if let Some(component) = components.next() {
73 match v {
74 SchemaNode::ValidNode(ValidNode::ObjectNode(mut object_node)) => {
75 let child_key = component.as_str_slice();
76 if let Some(child) = object_node.properties.remove(child_key) {
77 let child_is_required = object_node.required.contains(child_key);
78 let (child_opt, taken_opt) = take(child, child_is_required, components);
79 if let Some(child) = child_opt {
80 object_node.properties.insert(child_key.to_owned(), child);
81 };
82 if object_node.properties.is_empty() {
83 (None, taken_opt)
84 } else {
85 (Some(object_node.into()), taken_opt)
86 }
87 } else {
88 (Some(object_node.into()), None)
89 }
90 }
91 as_is => (Some(as_is), None),
92 }
93 } else {
94 let qn = QueryNode {
95 is_required,
96 schema: v,
97 };
98 (None, Some(qn))
99 }
100}
101
102fn insert<'v, 'p, P: PathComponent<'p>, I: Iterator<Item = P>>(
103 v: &'v mut SchemaNode,
104 mut components: I,
105 insertee: QueryNode<SchemaNode>,
106) -> Result<(), QueryNode<SchemaNode>> {
107 if let Some(component) = components.next() {
108 match *v {
109 SchemaNode::ValidNode(ValidNode::ObjectNode(ref mut object_node)) => {
110 let child_key = component.as_str_slice();
111
112 if let Some(ref mut child) = object_node.properties.get_mut(child_key) {
113 insert(child, components, insertee)
114 } else {
115 let mut child = SchemaNode::object().into();
116 let () = insert(&mut child, components, insertee)
117 .expect("Failed to insert into a newly created node");
118
119 object_node.properties.insert(child_key.to_owned(), child);
120 Ok(())
121 }
122 }
123 _ => Err(insertee),
124 }
125 } else {
126 *v = insertee.schema;
127 Ok(())
128 }
129}