Software /
code /
prosody
Comparison
util/datamapper.lua @ 11467:88792dd2bee9
util.datamapper: Factor out handling of object properties for array reuse
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 20 Mar 2021 21:25:45 +0100 |
parent | 11466:c098d07e6717 |
child | 11468:348b191cd850 |
comparison
equal
deleted
inserted
replaced
11466:c098d07e6717 | 11467:88792dd2bee9 |
---|---|
181 else | 181 else |
182 error("top-level scalars unsupported") | 182 error("top-level scalars unsupported") |
183 end | 183 end |
184 end | 184 end |
185 | 185 |
186 local function unparse(schema, t, current_name, current_ns, ctx) | 186 local unparse |
187 | |
188 local function unparse_property(out, v, proptype, propschema, value_where, name, namespace, current_ns, prefix, single_attribute) | |
189 if value_where == "in_attribute" then | |
190 local attr = name | |
191 if prefix then | |
192 attr = prefix .. ":" .. name | |
193 elseif namespace ~= current_ns then | |
194 attr = namespace .. "\1" .. name | |
195 end | |
196 | |
197 if proptype == "string" and type(v) == "string" then | |
198 out.attr[attr] = v | |
199 elseif proptype == "number" and type(v) == "number" then | |
200 out.attr[attr] = string.format("%g", v) | |
201 elseif proptype == "integer" and type(v) == "number" then | |
202 out.attr[attr] = string.format("%d", v) | |
203 elseif proptype == "boolean" then | |
204 out.attr[attr] = v and "1" or "0" | |
205 end | |
206 elseif value_where == "in_text" then | |
207 if type(v) == "string" then | |
208 out:text(v) | |
209 end | |
210 elseif value_where == "in_single_attribute" then | |
211 assert(single_attribute) | |
212 local propattr = {} | |
213 | |
214 if namespace ~= current_ns then | |
215 propattr.xmlns = namespace | |
216 end | |
217 | |
218 if proptype == "string" and type(v) == "string" then | |
219 propattr[single_attribute] = v | |
220 elseif proptype == "number" and type(v) == "number" then | |
221 propattr[single_attribute] = string.format("%g", v) | |
222 elseif proptype == "integer" and type(v) == "number" then | |
223 propattr[single_attribute] = string.format("%d", v) | |
224 elseif proptype == "boolean" and type(v) == "boolean" then | |
225 propattr[single_attribute] = v and "1" or "0" | |
226 end | |
227 out:tag(name, propattr):up(); | |
228 | |
229 else | |
230 local propattr | |
231 if namespace ~= current_ns then | |
232 propattr = {xmlns = namespace} | |
233 end | |
234 if value_where == "in_tag_name" then | |
235 if proptype == "string" and type(v) == "string" then | |
236 out:tag(v, propattr):up(); | |
237 elseif proptype == "boolean" and v == true then | |
238 out:tag(name, propattr):up(); | |
239 end | |
240 elseif proptype == "string" and type(v) == "string" then | |
241 out:text_tag(name, v, propattr) | |
242 elseif proptype == "number" and type(v) == "number" then | |
243 out:text_tag(name, string.format("%g", v), propattr) | |
244 elseif proptype == "integer" and type(v) == "number" then | |
245 out:text_tag(name, string.format("%d", v), propattr) | |
246 elseif proptype == "boolean" and type(v) == "boolean" then | |
247 out:text_tag(name, v and "1" or "0", propattr) | |
248 elseif proptype == "object" and type(propschema) == "table" and type(v) == "table" then | |
249 local c = unparse(propschema, v, name, namespace); | |
250 if c then | |
251 out:add_direct_child(c); | |
252 end | |
253 elseif proptype == "array" and type(propschema) == "table" and type(v) == "table" then | |
254 if value_where == "in_wrapper" then | |
255 local c = unparse(propschema, v, name, namespace); | |
256 if c then | |
257 out:add_direct_child(c); | |
258 end | |
259 else | |
260 unparse(propschema, v, name, namespace, out); | |
261 end | |
262 end | |
263 end | |
264 end | |
265 | |
266 function unparse(schema, t, current_name, current_ns, ctx) | |
187 | 267 |
188 if schema.xml then | 268 if schema.xml then |
189 if schema.xml.name then | 269 if schema.xml.name then |
190 current_name = schema.xml.name | 270 current_name = schema.xml.name |
191 end | 271 end |
201 | 281 |
202 for prop, propschema in pairs(schema.properties) do | 282 for prop, propschema in pairs(schema.properties) do |
203 local v = t[prop] | 283 local v = t[prop] |
204 | 284 |
205 if v ~= nil then | 285 if v ~= nil then |
206 | |
207 local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(propschema, prop, current_ns) | 286 local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(propschema, prop, current_ns) |
208 | 287 unparse_property(out, v, proptype, propschema, value_where, name, namespace, current_ns, prefix, single_attribute) |
209 if value_where == "in_attribute" then | |
210 local attr = name | |
211 if prefix then | |
212 attr = prefix .. ":" .. name | |
213 elseif namespace ~= current_ns then | |
214 attr = namespace .. "\1" .. name | |
215 end | |
216 | |
217 if proptype == "string" and type(v) == "string" then | |
218 out.attr[attr] = v | |
219 elseif proptype == "number" and type(v) == "number" then | |
220 out.attr[attr] = string.format("%g", v) | |
221 elseif proptype == "integer" and type(v) == "number" then | |
222 out.attr[attr] = string.format("%d", v) | |
223 elseif proptype == "boolean" then | |
224 out.attr[attr] = v and "1" or "0" | |
225 end | |
226 elseif value_where == "in_text" then | |
227 if type(v) == "string" then | |
228 out:text(v) | |
229 end | |
230 elseif value_where == "in_single_attribute" then | |
231 local propattr = {} | |
232 | |
233 if namespace ~= current_ns then | |
234 propattr.xmlns = namespace | |
235 end | |
236 | |
237 if proptype == "string" and type(v) == "string" then | |
238 propattr[single_attribute] = v | |
239 elseif proptype == "number" and type(v) == "number" then | |
240 propattr[single_attribute] = string.format("%g", v) | |
241 elseif proptype == "integer" and type(v) == "number" then | |
242 propattr[single_attribute] = string.format("%d", v) | |
243 elseif proptype == "boolean" and type(v) == "boolean" then | |
244 propattr[single_attribute] = v and "1" or "0" | |
245 end | |
246 out:tag(name, propattr):up(); | |
247 | |
248 else | |
249 local propattr | |
250 if namespace ~= current_ns then | |
251 propattr = {xmlns = namespace} | |
252 end | |
253 if value_where == "in_tag_name" then | |
254 if proptype == "string" and type(v) == "string" then | |
255 out:tag(v, propattr):up(); | |
256 elseif proptype == "boolean" and v == true then | |
257 out:tag(name, propattr):up(); | |
258 end | |
259 elseif proptype == "string" and type(v) == "string" then | |
260 out:text_tag(name, v, propattr) | |
261 elseif proptype == "number" and type(v) == "number" then | |
262 out:text_tag(name, string.format("%g", v), propattr) | |
263 elseif proptype == "integer" and type(v) == "number" then | |
264 out:text_tag(name, string.format("%d", v), propattr) | |
265 elseif proptype == "boolean" and type(v) == "boolean" then | |
266 out:text_tag(name, v and "1" or "0", propattr) | |
267 elseif proptype == "object" and type(propschema) == "table" and type(v) == "table" then | |
268 local c = unparse(propschema, v, name, namespace); | |
269 if c then | |
270 out:add_direct_child(c); | |
271 end | |
272 elseif proptype == "array" and type(propschema) == "table" and type(v) == "table" then | |
273 if value_where == "in_wrapper" then | |
274 local c = unparse(propschema, v, name, namespace); | |
275 if c then | |
276 out:add_direct_child(c); | |
277 end | |
278 else | |
279 unparse(propschema, v, name, namespace, out); | |
280 end | |
281 else | |
282 error("NYI") | |
283 end | |
284 end | |
285 end | 288 end |
286 end | 289 end |
287 return out | 290 return out |
288 | 291 |
289 elseif schema.type == "array" then | 292 elseif schema.type == "array" then |