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