Software /
code /
prosody
Changeset
11465:19a88b61ab4e
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.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 20 Mar 2021 19:02:18 +0100 |
parents | 11464:6e25409fecbd |
children | 11466:c098d07e6717 |
files | teal-src/util/datamapper.tl util/datamapper.lua |
diffstat | 2 files changed, 84 insertions(+), 80 deletions(-) [+] |
line wrap: on
line diff
--- a/teal-src/util/datamapper.tl Fri Mar 19 19:07:25 2021 +0100 +++ b/teal-src/util/datamapper.tl Sat Mar 20 19:02:18 2021 +0100 @@ -115,6 +115,45 @@ 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 @@ 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 @@ 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
--- a/util/datamapper.lua Fri Mar 19 19:07:25 2021 +0100 +++ b/util/datamapper.lua Sat Mar 20 19:02:18 2021 +0100 @@ -82,6 +82,45 @@ 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 @@ 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 @@ 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