# HG changeset patch # User Kim Alvefur # Date 1615687597 -3600 # Node ID a5050e21ab088adf14372b347fe0bffd76e71782 # Parent 1d9c1893cc5e95e4b7f47e79b82277f467288a67 util.datamapper: Separate extraction of xml from coercion to target type Now it gets the text, attribute or name first, then turns it into whatever the schema wants. This should be easier to further factor out into preparation for array support. diff -r 1d9c1893cc5e -r a5050e21ab08 teal-src/util/datamapper.tl --- a/teal-src/util/datamapper.tl Sun Mar 14 01:57:00 2021 +0100 +++ b/teal-src/util/datamapper.tl Sun Mar 14 03:06:37 2021 +0100 @@ -27,6 +27,18 @@ return true elseif s == "false" or s == "0" then return false + elseif s then + return true + end +end + +local function totype(t : js.schema_t.type_e, s : string) : any + if t == "string" then + return s; + elseif t == "boolean" then + return toboolean(s) + elseif t == "number" or t == "integer" then + return tonumber(s) end end @@ -58,6 +70,10 @@ proptype = propschema end + if proptype == "object" or proptype == "array" then + value_where = "in_children" + end + if propschema is js.schema_t and propschema.xml then if propschema.xml.name then name = propschema.xml.name @@ -88,6 +104,7 @@ end end + local value : string if value_where == "in_tag_name" then local c : st.stanza_t if proptype == "boolean" then @@ -103,11 +120,7 @@ else c = s:get_child(nil, namespace); end - if c and proptype == "string" then - out[prop] = c.name; - elseif proptype == "boolean" and c then - out[prop] = true; - end + value = c.name; elseif value_where == "in_attribute" then local attr = name if prefix then @@ -115,40 +128,18 @@ elseif namespace ~= s.attr.xmlns then attr = namespace .. "\1" .. name end - if proptype == "string" then - out[prop] = s.attr[attr] - elseif proptype == "integer" or proptype == "number" then - -- TODO floor if integer ? - out[prop] = tonumber(s.attr[attr]) - elseif proptype == "boolean" then - out[prop] = toboolean(s.attr[attr]) - -- else TODO - end + value = s.attr[attr] elseif value_where == "in_text" then - if proptype == "string" then - out[prop] = s:get_text() - elseif proptype == "integer" or proptype == "number" then - out[prop] = tonumber(s:get_text()) - end + value = s:get_text() elseif value_where == "in_single_attribute" then local c = s:get_child(name, namespace) - local a = c and c.attr[single_attribute] - if proptype == "string" then - out[prop] = a - elseif proptype == "integer" or proptype == "number" then - out[prop] = tonumber(a) - elseif proptype == "boolean" then - out[prop] = toboolean(a) - end - else - - if proptype == "string" then - out[prop] = s:get_child_text(name, namespace) - elseif proptype == "integer" or proptype == "number" then - out[prop] = tonumber(s:get_child_text(name, namespace)) - elseif proptype == "object" and propschema is js.schema_t then + 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 js.schema_t then + if proptype == "object" then local c = s:get_child(name, namespace) if c then out[prop] = parse_object(propschema, c); @@ -156,6 +147,9 @@ -- else TODO end end + if value_where ~= "in_children" then + out[prop] = totype(proptype, value) + end end end diff -r 1d9c1893cc5e -r a5050e21ab08 util/datamapper.lua --- a/util/datamapper.lua Sun Mar 14 01:57:00 2021 +0100 +++ b/util/datamapper.lua Sun Mar 14 03:06:37 2021 +0100 @@ -5,6 +5,18 @@ return true elseif s == "false" or s == "0" then return false + elseif s then + return true + end +end + +local function totype(t, s) + if t == "string" then + return s + elseif t == "boolean" then + return toboolean(s) + elseif t == "number" or t == "integer" then + return tonumber(s) end end @@ -29,6 +41,10 @@ proptype = propschema end + if proptype == "object" or proptype == "array" then + value_where = "in_children" + end + if type(propschema) == "table" and propschema.xml then if propschema.xml.name then name = propschema.xml.name @@ -59,6 +75,7 @@ end end + local value if value_where == "in_tag_name" then local c if proptype == "boolean" then @@ -74,11 +91,7 @@ else c = s:get_child(nil, namespace); end - if c and proptype == "string" then - out[prop] = c.name; - elseif proptype == "boolean" and c then - out[prop] = true; - end + value = c.name; elseif value_where == "in_attribute" then local attr = name if prefix then @@ -86,40 +99,18 @@ elseif namespace ~= s.attr.xmlns then attr = namespace .. "\1" .. name end - if proptype == "string" then - out[prop] = s.attr[attr] - elseif proptype == "integer" or proptype == "number" then - - out[prop] = tonumber(s.attr[attr]) - elseif proptype == "boolean" then - out[prop] = toboolean(s.attr[attr]) - - end + value = s.attr[attr] elseif value_where == "in_text" then - if proptype == "string" then - out[prop] = s:get_text() - elseif proptype == "integer" or proptype == "number" then - out[prop] = tonumber(s:get_text()) - end + value = s:get_text() elseif value_where == "in_single_attribute" then local c = s:get_child(name, namespace) - local a = c and c.attr[single_attribute] - if proptype == "string" then - out[prop] = a - elseif proptype == "integer" or proptype == "number" then - out[prop] = tonumber(a) - elseif proptype == "boolean" then - out[prop] = toboolean(a) - end - else - - if proptype == "string" then - out[prop] = s:get_child_text(name, namespace) - elseif proptype == "integer" or proptype == "number" then - out[prop] = tonumber(s:get_child_text(name, namespace)) - elseif proptype == "object" and type(propschema) == "table" then + 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 proptype == "object" then local c = s:get_child(name, namespace) if c then out[prop] = parse_object(propschema, c); @@ -127,6 +118,9 @@ end end + if value_where ~= "in_children" then + out[prop] = totype(proptype, value) + end end end