Mercurial > prosody-hg
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 |
| parents | c098d07e6717 |
| children | 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 |
