Software /
code /
prosody
Comparison
teal-src/util/datamapper.tl @ 11457:6a51749af7f4
util.datamapper: Add initial support for parsing arrays
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 18 Mar 2021 12:57:25 +0100 |
parent | 11456:4e376a43fe40 |
child | 11458:0e00fa518688 |
comparison
equal
deleted
inserted
replaced
11456:4e376a43fe40 | 11457:6a51749af7f4 |
---|---|
47 "in_text" | 47 "in_text" |
48 "in_text_tag" | 48 "in_text_tag" |
49 "in_attribute" | 49 "in_attribute" |
50 "in_single_attribute" | 50 "in_single_attribute" |
51 "in_children" | 51 "in_children" |
52 "in_wrapper" | |
52 end | 53 end |
53 | 54 |
54 local function unpack_propschema( propschema : js.schema_t | js.schema_t.type_e, propname : string, current_ns : string ) | 55 local function unpack_propschema( propschema : js.schema_t | js.schema_t.type_e, propname : string, current_ns : string ) |
55 : js.schema_t.type_e, value_goes, string, string, string, string, { any } | 56 : js.schema_t.type_e, value_goes, string, string, string, string, { any } |
56 local proptype : js.schema_t.type_e = "string" | 57 local proptype : js.schema_t.type_e = "string" |
65 proptype = propschema.type | 66 proptype = propschema.type |
66 elseif propschema is js.schema_t.type_e then | 67 elseif propschema is js.schema_t.type_e then |
67 proptype = propschema | 68 proptype = propschema |
68 end | 69 end |
69 | 70 |
71 if proptype == "object" or proptype == "array" then | |
72 value_where = "in_children" | |
73 end | |
74 | |
70 if propschema is js.schema_t then | 75 if propschema is js.schema_t then |
71 local xml = propschema.xml | 76 local xml = propschema.xml |
72 if xml then | 77 if xml then |
73 if xml.name then | 78 if xml.name then |
74 name = xml.name | 79 name = xml.name |
77 namespace = xml.namespace | 82 namespace = xml.namespace |
78 end | 83 end |
79 if xml.prefix then | 84 if xml.prefix then |
80 prefix = xml.prefix | 85 prefix = xml.prefix |
81 end | 86 end |
82 | 87 if proptype == "array" and xml.wrapped then |
83 if xml.attribute then | 88 value_where = "in_wrapper" |
89 elseif xml.attribute then | |
84 value_where = "in_attribute" | 90 value_where = "in_attribute" |
85 elseif xml.text then | 91 elseif xml.text then |
86 value_where = "in_text" | 92 value_where = "in_text" |
87 elseif xml.x_name_is_value then | 93 elseif xml.x_name_is_value then |
88 value_where = "in_tag_name" | 94 value_where = "in_tag_name" |
96 elseif propschema["enum"] then | 102 elseif propschema["enum"] then |
97 enums = propschema["enum"] | 103 enums = propschema["enum"] |
98 end | 104 end |
99 end | 105 end |
100 | 106 |
101 if proptype == "object" or proptype == "array" then | |
102 value_where = "in_children" | |
103 end | |
104 | |
105 return proptype, value_where, name, namespace, prefix, single_attribute, enums | 107 return proptype, value_where, name, namespace, prefix, single_attribute, enums |
106 end | 108 end |
107 | 109 |
108 | 110 local parse_object : function (schema : js.schema_t, s : st.stanza_t) : { string : any } |
109 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table | 111 local parse_array : function (schema : js.schema_t, s : st.stanza_t) : { any } |
112 | |
113 function parse_object (schema : js.schema_t, s : st.stanza_t) : { string : any } | |
110 local out : { string : any } = {} | 114 local out : { string : any } = {} |
111 if schema.properties then | 115 if schema.properties then |
112 for prop, propschema in pairs(schema.properties) do | 116 for prop, propschema in pairs(schema.properties) do |
113 | 117 |
114 local proptype, value_where, name, namespace, prefix, single_attribute, enums = unpack_propschema(propschema, prop, s.attr.xmlns) | 118 local proptype, value_where, name, namespace, prefix, single_attribute, enums = unpack_propschema(propschema, prop, s.attr.xmlns) |
151 if proptype == "object" then | 155 if proptype == "object" then |
152 local c = s:get_child(name, namespace) | 156 local c = s:get_child(name, namespace) |
153 if c then | 157 if c then |
154 out[prop] = parse_object(propschema, c); | 158 out[prop] = parse_object(propschema, c); |
155 end | 159 end |
156 -- else TODO | 160 elseif proptype == "array" then |
161 out[prop] = parse_array(propschema, s); | |
162 else | |
163 error "unreachable" | |
157 end | 164 end |
158 end | 165 elseif value_where == "in_wrapper" and propschema is js.schema_t and proptype == "array" then |
159 if value_where ~= "in_children" then | 166 local wrapper = s:get_child(name, namespace); |
167 if wrapper then | |
168 out[prop] = parse_array(propschema, wrapper); | |
169 else | |
170 error "unreachable" | |
171 end | |
172 else | |
173 error "unreachable" | |
174 end | |
175 if value_where ~= "in_children" and value_where ~= "in_wrapper" then | |
160 out[prop] = totype(proptype, value) | 176 out[prop] = totype(proptype, value) |
161 end | 177 end |
162 end | 178 end |
163 end | 179 end |
164 | 180 |
165 return out | 181 return out |
182 end | |
183 | |
184 function parse_array (schema : js.schema_t, s : st.stanza_t) : { any } | |
185 local proptype, value_where, child_name, namespace = unpack_propschema(schema.items, nil, s.attr.xmlns) | |
186 local out : { any } = {} | |
187 for c in s:childtags(child_name, namespace) do | |
188 local value : string; | |
189 if value_where == "in_text_tag" then | |
190 value = c:get_text(); | |
191 else | |
192 error "NYI" | |
193 end | |
194 | |
195 if value ~= nil then | |
196 table.insert(out, value); | |
197 end | |
198 end | |
199 return out; | |
166 end | 200 end |
167 | 201 |
168 local function parse (schema : js.schema_t, s : st.stanza_t) : table | 202 local function parse (schema : js.schema_t, s : st.stanza_t) : table |
169 if schema.type == "object" then | 203 if schema.type == "object" then |
170 return parse_object(schema, s) | 204 return parse_object(schema, s) |
205 elseif schema.type == "array" then | |
206 return parse_array(schema, s) | |
207 else | |
208 error "top-level scalars unsupported" | |
171 end | 209 end |
172 end | 210 end |
173 | 211 |
174 local function unparse ( schema : js.schema_t, t : table, current_name : string, current_ns : string ) : st.stanza_t | 212 local function unparse ( schema : js.schema_t, t : table, current_name : string, current_ns : string ) : st.stanza_t |
175 if schema.type == "object" then | 213 if schema.type == "object" then |