diff options
author | Kim Alvefur <zash@zash.se> | 2021-03-20 19:02:18 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2021-03-20 19:02:18 +0100 |
commit | 87474145e51cd0460e8c6608c2dcb7a712d9ef3c (patch) | |
tree | 3952f763a56e48033552eec82da5fedc09564ee4 /teal-src/util/datamapper.tl | |
parent | a51587da480c7521b020e8de3834b61a0e7e2928 (diff) | |
download | prosody-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.
Diffstat (limited to 'teal-src/util/datamapper.tl')
-rw-r--r-- | teal-src/util/datamapper.tl | 82 |
1 files changed, 42 insertions, 40 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 |