util.datamapper: Limited support for unparsing simple arrays of strings
authorKim Alvefur <zash@zash.se>
Thu, 18 Mar 2021 13:07:10 +0100
changeset 11462 0e00fa518688
parent 11461 6a51749af7f4
child 11463 86904555bffc
util.datamapper: Limited support for unparsing simple arrays of strings
spec/util_datamapper_spec.lua
teal-src/util/datamapper.tl
util/datamapper.lua
--- a/spec/util_datamapper_spec.lua	Thu Mar 18 12:57:25 2021 +0100
+++ b/spec/util_datamapper_spec.lua	Thu Mar 18 13:07:10 2021 +0100
@@ -103,15 +103,11 @@
 			assert.same(x:get_child("delay", "urn:xmpp:delay").attr, u:get_child("delay", "urn:xmpp:delay").attr);
 			assert.same(x:get_child("origin-id", "urn:xmpp:sid:0").attr, u:get_child("origin-id", "urn:xmpp:sid:0").attr);
 			for _, tag in ipairs(x.tags) do
-				if tag.name ~= "UNRELATED" and tag.name ~= "reactions" then
+				if tag.name ~= "UNRELATED" then
 					assert.truthy(u:get_child(tag.name, tag.attr.xmlns) or u:get_child(tag.name), tag:top_tag())
 				end
 			end
-			assert.equal(#x.tags-2, #u.tags)
-
-			pending("arrays", function ()
-				assert.truthy(u:get_child("reactions", "urn:xmpp:reactions:0"))
-			end);
+			assert.equal(#x.tags-1, #u.tags)
 
 		end);
 	end);
--- a/teal-src/util/datamapper.tl	Thu Mar 18 12:57:25 2021 +0100
+++ b/teal-src/util/datamapper.tl	Thu Mar 18 13:07:10 2021 +0100
@@ -192,6 +192,8 @@
 			error "NYI"
 		end
 
+		value = totype(proptype, value)
+
 		if value ~= nil then
 			table.insert(out, value);
 		end
@@ -210,7 +212,6 @@
 end
 
 local function unparse ( schema : js.schema_t, t : table, current_name : string, current_ns : string ) : st.stanza_t
-	if schema.type == "object" then
 
 		if schema.xml then
 			if schema.xml.name then
@@ -224,6 +225,8 @@
 
 		local out = st.stanza(current_name, { xmlns = current_ns })
 
+	if schema.type == "object" then
+
 		for prop, propschema in pairs(schema.properties) do
 			local v = t[prop]
 
@@ -294,13 +297,40 @@
 						if c then
 							out:add_direct_child(c);
 						end
-					-- else TODO
+					elseif proptype == "array" and propschema is js.schema_t and v is table then
+						local c = unparse(propschema, v, name, namespace);
+						if c then
+							if value_where == "in_wrapper" then
+								local w = st.stanza(propschema.xml.name or name, { xmlns = propschema.xml.namespace or namespace })
+								w:add_direct_child(c);
+								out:add_direct_child(w);
+							else
+								out:add_direct_child(c);
+							end
+						end
+					else
+						error "NYI"
 					end
 				end
 			end
 		end
 		return out;
 
+	elseif schema.type == "array" then
+		local proptype, value_where, name, namespace = unpack_propschema(schema.items, current_name, current_ns)
+		-- TODO , prefix, single_attribute
+		if proptype == "string" then
+			for _, item in ipairs(t as { string }) do
+				if value_where == "in_text_tag" then
+					out:text_tag(name, item, { xmlns = namespace });
+				else
+					error "NYI"
+				end
+			end
+		else
+			error "NYI"
+		end
+		return out;
 	end
 end
 
--- a/util/datamapper.lua	Thu Mar 18 12:57:25 2021 +0100
+++ b/util/datamapper.lua	Thu Mar 18 13:07:10 2021 +0100
@@ -162,6 +162,8 @@
 			error("NYI")
 		end
 
+		value = totype(proptype, value)
+
 		if value ~= nil then
 			table.insert(out, value);
 		end
@@ -180,19 +182,20 @@
 end
 
 local function unparse(schema, t, current_name, current_ns)
-	if schema.type == "object" then
 
-		if schema.xml then
-			if schema.xml.name then
-				current_name = schema.xml.name
-			end
-			if schema.xml.namespace then
-				current_ns = schema.xml.namespace
-			end
-
+	if schema.xml then
+		if schema.xml.name then
+			current_name = schema.xml.name
+		end
+		if schema.xml.namespace then
+			current_ns = schema.xml.namespace
 		end
 
-		local out = st.stanza(current_name, {xmlns = current_ns})
+	end
+
+	local out = st.stanza(current_name, {xmlns = current_ns})
+
+	if schema.type == "object" then
 
 		for prop, propschema in pairs(schema.properties) do
 			local v = t[prop]
@@ -264,13 +267,40 @@
 						if c then
 							out:add_direct_child(c);
 						end
-
+					elseif proptype == "array" and type(propschema) == "table" and type(v) == "table" then
+						local c = unparse(propschema, v, name, namespace);
+						if c then
+							if value_where == "in_wrapper" then
+								local w = st.stanza(propschema.xml.name or name, {xmlns = propschema.xml.namespace or namespace})
+								w:add_direct_child(c);
+								out:add_direct_child(w);
+							else
+								out:add_direct_child(c);
+							end
+						end
+					else
+						error("NYI")
 					end
 				end
 			end
 		end
 		return out
 
+	elseif schema.type == "array" then
+		local proptype, value_where, name, namespace = unpack_propschema(schema.items, current_name, current_ns)
+
+		if proptype == "string" then
+			for _, item in ipairs(t) do
+				if value_where == "in_text_tag" then
+					out:text_tag(name, item, {xmlns = namespace});
+				else
+					error("NYI")
+				end
+			end
+		else
+			error("NYI")
+		end
+		return out
 	end
 end