Changeset

11454:1d9c1893cc5e

util.datamapper: Use enum instead of mutually exclusive booleans Cleaner and rules out invalid combinations.
author Kim Alvefur <zash@zash.se>
date Sun, 14 Mar 2021 01:57:00 +0100
parents 11453:f0037234b2e9
children 11455:a5050e21ab08
files teal-src/util/datamapper.tl util/datamapper.lua
diffstat 2 files changed, 47 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/teal-src/util/datamapper.tl	Fri Mar 12 01:33:15 2021 +0100
+++ b/teal-src/util/datamapper.tl	Sun Mar 14 01:57:00 2021 +0100
@@ -30,6 +30,15 @@
 	end
 end
 
+local enum value_goes
+	"in_tag_name"
+	"in_text"
+	"in_text_tag"
+	"in_attribute"
+	"in_single_attribute"
+	"in_children"
+end
+
 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table
 	local out : { string : any } = {}
 	if schema.properties then
@@ -38,9 +47,7 @@
 			local name = prop
 			local namespace = s.attr.xmlns;
 			local prefix : string = nil
-			local is_attribute = false
-			local is_text = false
-			local name_is_value = false;
+			local value_where : value_goes = "in_text_tag"
 			local single_attribute : string
 			local enums : { any }
 
@@ -62,16 +69,17 @@
 					prefix = propschema.xml.prefix
 				end
 				if propschema.xml.attribute then
-					is_attribute = true
+					value_where = "in_attribute"
 				elseif propschema.xml.text then
 					-- XXX Not yet in OpenAPI
-					is_text = true
+					value_where = "in_text"
 				elseif propschema.xml.x_name_is_value then
 					-- XXX Custom extension
-					name_is_value = true
+					value_where = "in_tag_name"
 				elseif propschema.xml.x_single_attribute then
 					-- XXX Custom extension
 					single_attribute = propschema.xml.x_single_attribute
+					value_where = "in_single_attribute"
 				end
 				if propschema["const"] then
 					enums = { propschema["const"] }
@@ -80,7 +88,7 @@
 				end
 			end
 
-			if name_is_value then
+			if value_where == "in_tag_name" then
 				local c : st.stanza_t
 				if proptype == "boolean" then
 					c = s:get_child(name, namespace);
@@ -100,7 +108,7 @@
 				elseif proptype == "boolean" and c then
 					out[prop] = true;
 				end
-			elseif is_attribute then
+			elseif value_where == "in_attribute" then
 				local attr = name
 				if prefix then
 					attr = prefix .. ':' .. name
@@ -117,14 +125,14 @@
 				-- else TODO
 				end
 
-			elseif is_text then
+			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
 
-			elseif single_attribute then
+			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
@@ -189,9 +197,7 @@
 				local name = prop
 				local namespace = current_ns
 				local prefix : string = nil
-				local is_attribute = false
-				local is_text = false
-				local name_is_value = false;
+				local value_where : value_goes = "in_text_tag"
 				local single_attribute : string
 
 				if propschema is js.schema_t and propschema.xml then
@@ -208,17 +214,18 @@
 					end
 
 					if propschema.xml.attribute then
-						is_attribute = true
+						value_where = "in_attribute"
 					elseif propschema.xml.text then
-						is_text = true
+						value_where = "in_text"
 					elseif propschema.xml.x_name_is_value then
-						name_is_value = true
+						value_where = "in_tag_name"
 					elseif propschema.xml.x_single_attribute then
 						single_attribute = propschema.xml.x_single_attribute
+						value_where = "in_single_attribute"
 					end
 				end
 
-				if is_attribute then
+				if value_where == "in_attribute" then
 					local attr = name
 					if prefix then
 						attr = prefix .. ':' .. name
@@ -235,11 +242,11 @@
 					elseif proptype == "boolean" then
 						out.attr[attr] = v and "1" or "0"
 					end
-				elseif is_text then
+				elseif value_where == "in_text" then
 					if v is string then
 						out:text(v)
 					end
-				elseif single_attribute then
+				elseif value_where == "in_single_attribute" then
 					local propattr : { string : string } = {}
 
 					if namespace ~= current_ns then
@@ -262,7 +269,7 @@
 					if namespace ~= current_ns then
 						propattr = { xmlns = namespace }
 					end
-					if name_is_value then
+					if value_where == "in_tag_name" then
 						if proptype == "string" and v is string then
 							out:tag(v, propattr):up();
 						elseif proptype == "boolean" and v == true then
--- a/util/datamapper.lua	Fri Mar 12 01:33:15 2021 +0100
+++ b/util/datamapper.lua	Sun Mar 14 01:57:00 2021 +0100
@@ -8,6 +8,8 @@
 	end
 end
 
+local value_goes = {}
+
 local function parse_object(schema, s)
 	local out = {}
 	if schema.properties then
@@ -16,9 +18,7 @@
 			local name = prop
 			local namespace = s.attr.xmlns;
 			local prefix = nil
-			local is_attribute = false
-			local is_text = false
-			local name_is_value = false;
+			local value_where = "in_text_tag"
 			local single_attribute
 			local enums
 
@@ -40,16 +40,17 @@
 					prefix = propschema.xml.prefix
 				end
 				if propschema.xml.attribute then
-					is_attribute = true
+					value_where = "in_attribute"
 				elseif propschema.xml.text then
 
-					is_text = true
+					value_where = "in_text"
 				elseif propschema.xml.x_name_is_value then
 
-					name_is_value = true
+					value_where = "in_tag_name"
 				elseif propschema.xml.x_single_attribute then
 
 					single_attribute = propschema.xml.x_single_attribute
+					value_where = "in_single_attribute"
 				end
 				if propschema["const"] then
 					enums = {propschema["const"]}
@@ -58,7 +59,7 @@
 				end
 			end
 
-			if name_is_value then
+			if value_where == "in_tag_name" then
 				local c
 				if proptype == "boolean" then
 					c = s:get_child(name, namespace);
@@ -78,7 +79,7 @@
 				elseif proptype == "boolean" and c then
 					out[prop] = true;
 				end
-			elseif is_attribute then
+			elseif value_where == "in_attribute" then
 				local attr = name
 				if prefix then
 					attr = prefix .. ":" .. name
@@ -95,14 +96,14 @@
 
 				end
 
-			elseif is_text then
+			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
 
-			elseif single_attribute then
+			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
@@ -167,9 +168,7 @@
 				local name = prop
 				local namespace = current_ns
 				local prefix = nil
-				local is_attribute = false
-				local is_text = false
-				local name_is_value = false;
+				local value_where = "in_text_tag"
 				local single_attribute
 
 				if type(propschema) == "table" and propschema.xml then
@@ -186,17 +185,18 @@
 					end
 
 					if propschema.xml.attribute then
-						is_attribute = true
+						value_where = "in_attribute"
 					elseif propschema.xml.text then
-						is_text = true
+						value_where = "in_text"
 					elseif propschema.xml.x_name_is_value then
-						name_is_value = true
+						value_where = "in_tag_name"
 					elseif propschema.xml.x_single_attribute then
 						single_attribute = propschema.xml.x_single_attribute
+						value_where = "in_single_attribute"
 					end
 				end
 
-				if is_attribute then
+				if value_where == "in_attribute" then
 					local attr = name
 					if prefix then
 						attr = prefix .. ":" .. name
@@ -213,11 +213,11 @@
 					elseif proptype == "boolean" then
 						out.attr[attr] = v and "1" or "0"
 					end
-				elseif is_text then
+				elseif value_where == "in_text" then
 					if type(v) == "string" then
 						out:text(v)
 					end
-				elseif single_attribute then
+				elseif value_where == "in_single_attribute" then
 					local propattr = {}
 
 					if namespace ~= current_ns then
@@ -240,7 +240,7 @@
 					if namespace ~= current_ns then
 						propattr = {xmlns = namespace}
 					end
-					if name_is_value then
+					if value_where == "in_tag_name" then
 						if proptype == "string" and type(v) == "string" then
 							out:tag(v, propattr):up();
 						elseif proptype == "boolean" and v == true then