changeset 4309:e8b9228b5265

mod_rest: Optimize stanza to JSON mapping From O(#field_mappings ^ #s.tags) to O(#s.tags) Haven't actually benchmarked...
author Kim Alvefur <zash@zash.se>
date Wed, 16 Dec 2020 22:07:09 +0100
parents 2d42dd45638a
children b0ad1604f77e
files mod_rest/jsonmap.lib.lua
diffstat 1 files changed, 28 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/mod_rest/jsonmap.lib.lua	Mon Dec 21 16:01:28 2020 +0100
+++ b/mod_rest/jsonmap.lib.lua	Wed Dec 16 22:07:09 2020 +0100
@@ -406,6 +406,20 @@
 
 };
 
+local byxmlname = {};
+for k, spec in pairs(field_mappings) do
+	if type(spec) == "table" then
+		spec.key = k;
+		if spec.xmlns and spec.tagname then
+			byxmlname["{" .. spec.xmlns .. "}" .. spec.tagname] = spec;
+		elseif spec.type == "name" then
+			byxmlname["{" .. spec.xmlns .. "}"] = spec;
+		end
+	elseif type(spec) == "string" then
+		byxmlname["{jabber:client}" .. k] = {key = k; type = spec};
+	end
+end
+
 local implied_kinds = {
 	disco = "iq",
 	items = "iq",
@@ -472,31 +486,25 @@
 		return t;
 	end
 
-	for k, mapping in pairs(field_mappings) do
-		if mapping == "text_tag" then
-			t[k] = s:get_child_text(k);
+	for tag in s:children() do
+		local prefix = "{" .. (tag.attr.xmlns or "jabber:client") .. "}";
+		local mapping = byxmlname[prefix .. tag.name];
+		if not mapping then
+			mapping = byxmlname[prefix];
+		end
+
+		if not mapping then -- luacheck: ignore 542
+			-- pass
 		elseif mapping.type == "text_tag" then
-			t[k] = s:get_child_text(mapping.tagname, mapping.xmlns);
+			t[mapping.key] = tag:get_text();
 		elseif mapping.type == "name" then
-			local child = s:get_child(nil, mapping.xmlns);
-			if child then
-				t[k] = child.name;
-			end
+			t[mapping.key] = tag.name;
 		elseif mapping.type == "attr" then
-			local child = s:get_child(mapping.tagname, mapping.xmlns);
-			if child then
-				t[k] = child.attr[mapping.attr];
-			end
+			t[mapping.key] = tag.attr[mapping.attr];
 		elseif mapping.type == "bool_tag" then
-			if s:get_child(mapping.tagname, mapping.xmlns) then
-				t[k] = true;
-			end
+			t[mapping.key] = true;
 		elseif mapping.type == "func" and mapping.st2json then
-			local child = s:get_child(mapping.tagname, mapping.xmlns or k);
-			-- TODO handle err
-			if child then
-				t[k] = mapping.st2json(child);
-			end
+			t[mapping.key] = mapping.st2json(tag);
 		end
 	end