Mercurial > prosody-hg
comparison teal-src/util/datamapper.tl @ 11435:a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Based on the XML support in the OpenAPI specification.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 07 Mar 2021 00:57:36 +0100 |
| parents | |
| children | 5df9ffc25bb4 |
comparison
equal
deleted
inserted
replaced
| 11434:66d4067bdfb2 | 11435:a1fa6202fa13 |
|---|---|
| 1 local st = require "util.stanza"; | |
| 2 local js = require "util.jsonschema" | |
| 3 | |
| 4 local function toboolean ( s : string ) : boolean | |
| 5 if s == "true" or s == "1" then | |
| 6 return true | |
| 7 elseif s == "false" or s == "0" then | |
| 8 return false | |
| 9 end | |
| 10 end | |
| 11 | |
| 12 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table | |
| 13 local out : { string : any } = {} | |
| 14 if schema.properties then | |
| 15 for prop, propschema in pairs(schema.properties) do | |
| 16 -- TODO factor out, if it's generic enough | |
| 17 local name = prop | |
| 18 local namespace = s.attr.xmlns; | |
| 19 local prefix : string = nil | |
| 20 local is_attribute = false | |
| 21 local is_text = false | |
| 22 | |
| 23 local proptype : js.schema_t.type_e | |
| 24 if propschema is js.schema_t then | |
| 25 proptype = propschema.type | |
| 26 elseif propschema is js.schema_t.type_e then | |
| 27 proptype = propschema | |
| 28 end | |
| 29 | |
| 30 if propschema is js.schema_t and propschema.xml then | |
| 31 if propschema.xml.name then | |
| 32 name = propschema.xml.name | |
| 33 end | |
| 34 if propschema.xml.namespace then | |
| 35 namespace = propschema.xml.namespace | |
| 36 end | |
| 37 if propschema.xml.prefix then | |
| 38 prefix = propschema.xml.prefix | |
| 39 end | |
| 40 if propschema.xml.attribute then | |
| 41 is_attribute = true | |
| 42 elseif propschema.xml.text then | |
| 43 is_text = true | |
| 44 end | |
| 45 end | |
| 46 | |
| 47 if is_attribute then | |
| 48 local attr = name | |
| 49 if prefix then | |
| 50 attr = prefix .. ':' .. name | |
| 51 elseif namespace ~= s.attr.xmlns then | |
| 52 attr = namespace .. "\1" .. name | |
| 53 end | |
| 54 if proptype == "string" then | |
| 55 out[prop] = s.attr[attr] | |
| 56 elseif proptype == "integer" or proptype == "number" then | |
| 57 -- TODO floor if integer ? | |
| 58 out[prop] = tonumber(s.attr[attr]) | |
| 59 elseif proptype == "boolean" then | |
| 60 out[prop] = toboolean(s.attr[attr]) | |
| 61 -- else TODO | |
| 62 end | |
| 63 | |
| 64 elseif is_text then | |
| 65 if proptype == "string" then | |
| 66 out[prop] = s:get_text() | |
| 67 elseif proptype == "integer" or proptype == "number" then | |
| 68 out[prop] = tonumber(s:get_text()) | |
| 69 end | |
| 70 | |
| 71 else | |
| 72 | |
| 73 if proptype == "string" then | |
| 74 out[prop] = s:get_child_text(name, namespace) | |
| 75 elseif proptype == "integer" or proptype == "number" then | |
| 76 out[prop] = tonumber(s:get_child_text(name, namespace)) | |
| 77 elseif proptype == "object" and propschema is js.schema_t then | |
| 78 local c = s:get_child(name, namespace) | |
| 79 if c then | |
| 80 out[prop] = parse_object(propschema, c); | |
| 81 end | |
| 82 -- else TODO | |
| 83 end | |
| 84 end | |
| 85 end | |
| 86 end | |
| 87 | |
| 88 return out | |
| 89 end | |
| 90 | |
| 91 local function parse (schema : js.schema_t, s : st.stanza_t) : table | |
| 92 if schema.type == "object" then | |
| 93 return parse_object(schema, s) | |
| 94 end | |
| 95 end | |
| 96 | |
| 97 return { | |
| 98 parse = parse, | |
| 99 -- unparse = unparse, -- TODO | |
| 100 } |
