Diff

util/datamapper.lua @ 11455:a5050e21ab08

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.
author Kim Alvefur <zash@zash.se>
date Sun, 14 Mar 2021 03:06:37 +0100
parent 11454:1d9c1893cc5e
child 11456:4e376a43fe40
line wrap: on
line diff
--- 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