aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-03-20 19:02:18 +0100
committerKim Alvefur <zash@zash.se>2021-03-20 19:02:18 +0100
commit87474145e51cd0460e8c6608c2dcb7a712d9ef3c (patch)
tree3952f763a56e48033552eec82da5fedc09564ee4
parenta51587da480c7521b020e8de3834b61a0e7e2928 (diff)
downloadprosody-87474145e51cd0460e8c6608c2dcb7a712d9ef3c.tar.gz
prosody-87474145e51cd0460e8c6608c2dcb7a712d9ef3c.zip
util.datamapper: Factor out extraction of the XML part to use
So extract_value() takes an XML tag and details about which part we're interested in and returns that. Factoring this out will help with array implementation since this will be common behavior.
-rw-r--r--teal-src/util/datamapper.tl82
-rw-r--r--util/datamapper.lua82
2 files changed, 84 insertions, 80 deletions
diff --git a/teal-src/util/datamapper.tl b/teal-src/util/datamapper.tl
index 3cbc7fda..54ecdacf 100644
--- a/teal-src/util/datamapper.tl
+++ b/teal-src/util/datamapper.tl
@@ -115,6 +115,45 @@ end
local parse_object : function (schema : schema_t, s : st.stanza_t) : { string : any }
local parse_array : function (schema : schema_t, s : st.stanza_t) : { any }
+local function extract_value (s : st.stanza_t, value_where : value_goes, proptype : json.json_type_name, name : string, namespace : string, prefix : string, single_attribute : string, enums : { any }) : string
+ if value_where == "in_tag_name" then
+ local c : st.stanza_t
+ if proptype == "boolean" then
+ c = s:get_child(name, namespace);
+ elseif enums and proptype == "string" then
+ -- XXX O(n²) ?
+ -- Probably better to flip the table and loop over :childtags(nil, ns), should be 2xO(n)
+ -- BUT works first, optimize later
+ for i = 1, #enums do
+ c = s:get_child(enums[i] as string, namespace);
+ if c then break end
+ end
+ else
+ c = s:get_child(nil, namespace);
+ end
+ if c then
+ return c.name;
+ end
+ elseif value_where == "in_attribute" then
+ local attr = name
+ if prefix then
+ attr = prefix .. ':' .. name
+ elseif namespace ~= s.attr.xmlns then
+ attr = namespace .. "\1" .. name
+ end
+ return s.attr[attr]
+
+ elseif value_where == "in_text" then
+ return s:get_text()
+
+ elseif value_where == "in_single_attribute" then
+ local c = s:get_child(name, namespace)
+ return c and c.attr[single_attribute]
+ elseif value_where == "in_text_tag" then
+ return s:get_child_text(name, namespace)
+ end
+end
+
function parse_object (schema : schema_t, s : st.stanza_t) : { string : any }
local out : { string : any } = {}
if schema is json_schema_object and schema.properties then
@@ -122,43 +161,7 @@ function parse_object (schema : schema_t, s : st.stanza_t) : { string : any }
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
- local c : st.stanza_t
- if proptype == "boolean" then
- c = s:get_child(name, namespace);
- elseif enums and proptype == "string" then
- -- XXX O(n²) ?
- -- Probably better to flip the table and loop over :childtags(nil, ns), should be 2xO(n)
- -- BUT works first, optimize later
- for i = 1, #enums do
- c = s:get_child(enums[i] as string, namespace);
- if c then break end
- end
- else
- c = s:get_child(nil, namespace);
- end
- if c is st.stanza_t then
- value = c.name;
- end
- elseif value_where == "in_attribute" then
- local attr = name
- if prefix then
- attr = prefix .. ':' .. name
- elseif namespace ~= s.attr.xmlns then
- attr = namespace .. "\1" .. name
- end
- value = s.attr[attr]
-
- elseif value_where == "in_text" then
- value = s:get_text()
-
- elseif value_where == "in_single_attribute" then
- local c = s:get_child(name, namespace)
- value = c and c.attr[single_attribute]
- elseif value_where == "in_text_tag" then
- value = s:get_child_text(name, namespace)
- elseif value_where == "in_children" and propschema is json_schema_object then
+ if value_where == "in_children" and propschema is json_schema_object then
if proptype == "object" then
local c = s:get_child(name, namespace)
if c then
@@ -177,9 +180,8 @@ function parse_object (schema : schema_t, s : st.stanza_t) : { string : any }
error "unreachable"
end
else
- error "unreachable"
- end
- if value_where ~= "in_children" and value_where ~= "in_wrapper" then
+ local value : string = extract_value (s, value_where, proptype, name, namespace, prefix, single_attribute, enums)
+
out[prop] = totype(proptype, value)
end
end
diff --git a/util/datamapper.lua b/util/datamapper.lua
index cb008695..32d01050 100644
--- a/util/datamapper.lua
+++ b/util/datamapper.lua
@@ -82,6 +82,45 @@ end
local parse_object
local parse_array
+local function extract_value(s, value_where, proptype, name, namespace, prefix, single_attribute, enums)
+ if value_where == "in_tag_name" then
+ local c
+ if proptype == "boolean" then
+ c = s:get_child(name, namespace);
+ elseif enums and proptype == "string" then
+
+ for i = 1, #enums do
+ c = s:get_child(enums[i], namespace);
+ if c then
+ break
+ end
+ end
+ else
+ c = s:get_child(nil, namespace);
+ end
+ if c then
+ return c.name
+ end
+ elseif value_where == "in_attribute" then
+ local attr = name
+ if prefix then
+ attr = prefix .. ":" .. name
+ elseif namespace ~= s.attr.xmlns then
+ attr = namespace .. "\1" .. name
+ end
+ return s.attr[attr]
+
+ elseif value_where == "in_text" then
+ return s:get_text()
+
+ elseif value_where == "in_single_attribute" then
+ local c = s:get_child(name, namespace)
+ return c and c.attr[single_attribute]
+ elseif value_where == "in_text_tag" then
+ return s:get_child_text(name, namespace)
+ end
+end
+
function parse_object(schema, s)
local out = {}
if type(schema) == "table" and schema.properties then
@@ -89,43 +128,7 @@ function parse_object(schema, s)
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
- local c
- if proptype == "boolean" then
- c = s:get_child(name, namespace);
- elseif enums and proptype == "string" then
-
- for i = 1, #enums do
- c = s:get_child(enums[i], namespace);
- if c then
- break
- end
- end
- else
- c = s:get_child(nil, namespace);
- end
- if type(c) == "table" then
- value = c.name;
- end
- elseif value_where == "in_attribute" then
- local attr = name
- if prefix then
- attr = prefix .. ":" .. name
- elseif namespace ~= s.attr.xmlns then
- attr = namespace .. "\1" .. name
- end
- value = s.attr[attr]
-
- elseif value_where == "in_text" then
- value = s:get_text()
-
- elseif value_where == "in_single_attribute" then
- local c = s:get_child(name, namespace)
- value = c and c.attr[single_attribute]
- elseif value_where == "in_text_tag" then
- value = s:get_child_text(name, namespace)
- elseif value_where == "in_children" and type(propschema) == "table" then
+ if value_where == "in_children" and type(propschema) == "table" then
if proptype == "object" then
local c = s:get_child(name, namespace)
if c then
@@ -144,9 +147,8 @@ function parse_object(schema, s)
error("unreachable")
end
else
- error("unreachable")
- end
- if value_where ~= "in_children" and value_where ~= "in_wrapper" then
+ local value = extract_value(s, value_where, proptype, name, namespace, prefix, single_attribute, enums)
+
out[prop] = totype(proptype, value)
end
end