aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-03-14 16:50:49 +0100
committerKim Alvefur <zash@zash.se>2021-03-14 16:50:49 +0100
commitfb7df0067cf4a84b1fe7f9145b9aafb0ebae75fa (patch)
tree6451d06fff1cd969ee7359670089e7460a2d5d6e
parent3a62af2e0e6df40c2691f94eb2a496d8c45828ad (diff)
downloadprosody-fb7df0067cf4a84b1fe7f9145b9aafb0ebae75fa.tar.gz
prosody-fb7df0067cf4a84b1fe7f9145b9aafb0ebae75fa.zip
util.datamapper: Factor out common schema unpacking
This code extracts the bits from the schema that determines how the data is to be mapped to/from XML.
-rw-r--r--teal-src/util/datamapper.tl140
-rw-r--r--util/datamapper.lua133
2 files changed, 110 insertions, 163 deletions
diff --git a/teal-src/util/datamapper.tl b/teal-src/util/datamapper.tl
index 38a63004..055ddabd 100644
--- a/teal-src/util/datamapper.tl
+++ b/teal-src/util/datamapper.tl
@@ -51,58 +51,67 @@ local enum value_goes
"in_children"
end
-local function parse_object (schema : js.schema_t, s : st.stanza_t) : table
- local out : { string : any } = {}
- if schema.properties then
- for prop, propschema in pairs(schema.properties) do
- -- TODO factor out, if it's generic enough
- local name = prop
- local namespace = s.attr.xmlns;
- local prefix : string = nil
- local value_where : value_goes = "in_text_tag"
- local single_attribute : string
- local enums : { any }
+local function unpack_propschema( propschema : js.schema_t | js.schema_t.type_e, propname : string, current_ns : string )
+ : js.schema_t.type_e, value_goes, string, string, string, string, { any }
+ local proptype : js.schema_t.type_e = "string"
+ local value_where : value_goes = "in_text_tag"
+ local name = propname
+ local namespace = current_ns
+ local prefix : string
+ local single_attribute : string
+ local enums : { any }
- local proptype : js.schema_t.type_e
- if propschema is js.schema_t then
- proptype = propschema.type
- elseif propschema is js.schema_t.type_e then
- proptype = propschema
- end
+ if propschema is js.schema_t then
+ proptype = propschema.type
+ elseif propschema is js.schema_t.type_e then
+ proptype = propschema
+ end
- if proptype == "object" or proptype == "array" then
- value_where = "in_children"
+ if propschema is js.schema_t then
+ local xml = propschema.xml
+ if xml then
+ if xml.name then
+ name = xml.name
+ end
+ if xml.namespace then
+ namespace = xml.namespace
+ end
+ if xml.prefix then
+ prefix = xml.prefix
end
- if propschema is js.schema_t and propschema.xml then
- if propschema.xml.name then
- name = propschema.xml.name
- end
- if propschema.xml.namespace then
- namespace = propschema.xml.namespace
- end
- if propschema.xml.prefix then
- prefix = propschema.xml.prefix
- end
- if propschema.xml.attribute then
- value_where = "in_attribute"
- elseif propschema.xml.text then
- -- XXX Not yet in OpenAPI
- value_where = "in_text"
- elseif propschema.xml.x_name_is_value then
- -- XXX Custom extension
- value_where = "in_tag_name"
- elseif propschema.xml.x_single_attribute then
- -- XXX Custom extension
- single_attribute = propschema.xml.x_single_attribute
- value_where = "in_single_attribute"
- end
- if propschema["const"] then
- enums = { propschema["const"] }
- elseif propschema["enum"] then
- enums = propschema["enum"]
- end
+ if xml.attribute then
+ value_where = "in_attribute"
+ elseif xml.text then
+ value_where = "in_text"
+ elseif xml.x_name_is_value then
+ value_where = "in_tag_name"
+ elseif xml.x_single_attribute then
+ single_attribute = xml.x_single_attribute
+ value_where = "in_single_attribute"
end
+ end
+ if propschema["const"] then
+ enums = { propschema["const"] }
+ elseif propschema["enum"] then
+ enums = propschema["enum"]
+ end
+ end
+
+ if proptype == "object" or proptype == "array" then
+ value_where = "in_children"
+ end
+
+ return proptype, value_where, name, namespace, prefix, single_attribute, enums
+end
+
+
+local function parse_object (schema : js.schema_t, s : st.stanza_t) : table
+ local out : { string : any } = {}
+ if schema.properties then
+ for prop, propschema in pairs(schema.properties) do
+
+ local proptype, value_where, name, namespace, prefix, single_attribute, enums = unpack_propschema(propschema, prop, s.attr.xmlns)
local value : string
if value_where == "in_tag_name" then
@@ -181,43 +190,8 @@ local function unparse ( schema : js.schema_t, t : table, current_name : string,
local v = t[prop]
if v ~= nil then
- local proptype : js.schema_t.type_e
- if propschema is js.schema_t then
- proptype = propschema.type
- elseif propschema is js.schema_t.type_e then
- proptype = propschema
- end
- local name = prop
- local namespace = current_ns
- local prefix : string = nil
- local value_where : value_goes = "in_text_tag"
- local single_attribute : string
-
- if propschema is js.schema_t and propschema.xml then
-
- if propschema.xml.name then
- name = propschema.xml.name
- end
- if propschema.xml.namespace then
- namespace = propschema.xml.namespace
- end
-
- if propschema.xml.prefix then
- prefix = propschema.xml.prefix
- end
-
- if propschema.xml.attribute then
- value_where = "in_attribute"
- elseif propschema.xml.text then
- value_where = "in_text"
- elseif propschema.xml.x_name_is_value then
- value_where = "in_tag_name"
- elseif propschema.xml.x_single_attribute then
- single_attribute = propschema.xml.x_single_attribute
- value_where = "in_single_attribute"
- end
- end
+ local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(propschema, prop, current_ns)
if value_where == "in_attribute" then
local attr = name
diff --git a/util/datamapper.lua b/util/datamapper.lua
index d642c881..da46d072 100644
--- a/util/datamapper.lua
+++ b/util/datamapper.lua
@@ -22,58 +22,66 @@ end
local value_goes = {}
-local function parse_object(schema, s)
- local out = {}
- if schema.properties then
- for prop, propschema in pairs(schema.properties) do
+local function unpack_propschema(propschema, propname, current_ns)
+
+ local proptype = "string"
+ local value_where = "in_text_tag"
+ local name = propname
+ local namespace = current_ns
+ local prefix
+ local single_attribute
+ local enums
+
+ if type(propschema) == "table" then
+ proptype = propschema.type
+ elseif type(propschema) == "string" then
+ proptype = propschema
+ end
- local name = prop
- local namespace = s.attr.xmlns;
- local prefix = nil
- local value_where = "in_text_tag"
- local single_attribute
- local enums
-
- local proptype
- if type(propschema) == "table" then
- proptype = propschema.type
- elseif type(propschema) == "string" then
- proptype = propschema
+ if type(propschema) == "table" then
+ local xml = propschema.xml
+ if xml then
+ if xml.name then
+ name = xml.name
+ end
+ if xml.namespace then
+ namespace = xml.namespace
+ end
+ if xml.prefix then
+ prefix = xml.prefix
end
- if proptype == "object" or proptype == "array" then
- value_where = "in_children"
+ if xml.attribute then
+ value_where = "in_attribute"
+ elseif xml.text then
+ value_where = "in_text"
+ elseif xml.x_name_is_value then
+ value_where = "in_tag_name"
+ elseif xml.x_single_attribute then
+ single_attribute = xml.x_single_attribute
+ value_where = "in_single_attribute"
end
+ end
+ if propschema["const"] then
+ enums = {propschema["const"]}
+ elseif propschema["enum"] then
+ enums = propschema["enum"]
+ end
+ end
- if type(propschema) == "table" and propschema.xml then
- if propschema.xml.name then
- name = propschema.xml.name
- end
- if propschema.xml.namespace then
- namespace = propschema.xml.namespace
- end
- if propschema.xml.prefix then
- prefix = propschema.xml.prefix
- end
- if propschema.xml.attribute then
- value_where = "in_attribute"
- elseif propschema.xml.text then
+ if proptype == "object" or proptype == "array" then
+ value_where = "in_children"
+ end
- value_where = "in_text"
- elseif propschema.xml.x_name_is_value then
+ return proptype, value_where, name, namespace, prefix, single_attribute, enums
+end
- value_where = "in_tag_name"
- elseif propschema.xml.x_single_attribute then
+local function parse_object(schema, s)
+ local out = {}
+ if schema.properties then
+ for prop, propschema in pairs(schema.properties) do
- single_attribute = propschema.xml.x_single_attribute
- value_where = "in_single_attribute"
- end
- if propschema["const"] then
- enums = {propschema["const"]}
- elseif propschema["enum"] then
- enums = propschema["enum"]
- end
- end
+ local proptype, value_where, name, namespace, prefix, single_attribute, enums = unpack_propschema(propschema, prop, s.attr.xmlns)
local value
if value_where == "in_tag_name" then
@@ -152,43 +160,8 @@ local function unparse(schema, t, current_name, current_ns)
local v = t[prop]
if v ~= nil then
- local proptype
- if type(propschema) == "table" then
- proptype = propschema.type
- elseif type(propschema) == "string" then
- proptype = propschema
- end
-
- local name = prop
- local namespace = current_ns
- local prefix = nil
- local value_where = "in_text_tag"
- local single_attribute
- if type(propschema) == "table" and propschema.xml then
-
- if propschema.xml.name then
- name = propschema.xml.name
- end
- if propschema.xml.namespace then
- namespace = propschema.xml.namespace
- end
-
- if propschema.xml.prefix then
- prefix = propschema.xml.prefix
- end
-
- if propschema.xml.attribute then
- value_where = "in_attribute"
- elseif propschema.xml.text then
- value_where = "in_text"
- elseif propschema.xml.x_name_is_value then
- value_where = "in_tag_name"
- elseif propschema.xml.x_single_attribute then
- single_attribute = propschema.xml.x_single_attribute
- value_where = "in_single_attribute"
- end
- end
+ local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(propschema, prop, current_ns)
if value_where == "in_attribute" then
local attr = name