Software / code / prosody-modules
Comparison
mod_rest/jsonmap.lib.lua @ 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 |
| parent | 4251:d33b480befcb |
| child | 4372:78de3c7acf58 |
comparison
equal
deleted
inserted
replaced
| 4308:2d42dd45638a | 4309:e8b9228b5265 |
|---|---|
| 404 end; | 404 end; |
| 405 }; | 405 }; |
| 406 | 406 |
| 407 }; | 407 }; |
| 408 | 408 |
| 409 local byxmlname = {}; | |
| 410 for k, spec in pairs(field_mappings) do | |
| 411 if type(spec) == "table" then | |
| 412 spec.key = k; | |
| 413 if spec.xmlns and spec.tagname then | |
| 414 byxmlname["{" .. spec.xmlns .. "}" .. spec.tagname] = spec; | |
| 415 elseif spec.type == "name" then | |
| 416 byxmlname["{" .. spec.xmlns .. "}"] = spec; | |
| 417 end | |
| 418 elseif type(spec) == "string" then | |
| 419 byxmlname["{jabber:client}" .. k] = {key = k; type = spec}; | |
| 420 end | |
| 421 end | |
| 422 | |
| 409 local implied_kinds = { | 423 local implied_kinds = { |
| 410 disco = "iq", | 424 disco = "iq", |
| 411 items = "iq", | 425 items = "iq", |
| 412 ping = "iq", | 426 ping = "iq", |
| 413 version = "iq", | 427 version = "iq", |
| 470 by = error and error.attr.by or nil, | 484 by = error and error.attr.by or nil, |
| 471 }; | 485 }; |
| 472 return t; | 486 return t; |
| 473 end | 487 end |
| 474 | 488 |
| 475 for k, mapping in pairs(field_mappings) do | 489 for tag in s:children() do |
| 476 if mapping == "text_tag" then | 490 local prefix = "{" .. (tag.attr.xmlns or "jabber:client") .. "}"; |
| 477 t[k] = s:get_child_text(k); | 491 local mapping = byxmlname[prefix .. tag.name]; |
| 492 if not mapping then | |
| 493 mapping = byxmlname[prefix]; | |
| 494 end | |
| 495 | |
| 496 if not mapping then -- luacheck: ignore 542 | |
| 497 -- pass | |
| 478 elseif mapping.type == "text_tag" then | 498 elseif mapping.type == "text_tag" then |
| 479 t[k] = s:get_child_text(mapping.tagname, mapping.xmlns); | 499 t[mapping.key] = tag:get_text(); |
| 480 elseif mapping.type == "name" then | 500 elseif mapping.type == "name" then |
| 481 local child = s:get_child(nil, mapping.xmlns); | 501 t[mapping.key] = tag.name; |
| 482 if child then | |
| 483 t[k] = child.name; | |
| 484 end | |
| 485 elseif mapping.type == "attr" then | 502 elseif mapping.type == "attr" then |
| 486 local child = s:get_child(mapping.tagname, mapping.xmlns); | 503 t[mapping.key] = tag.attr[mapping.attr]; |
| 487 if child then | |
| 488 t[k] = child.attr[mapping.attr]; | |
| 489 end | |
| 490 elseif mapping.type == "bool_tag" then | 504 elseif mapping.type == "bool_tag" then |
| 491 if s:get_child(mapping.tagname, mapping.xmlns) then | 505 t[mapping.key] = true; |
| 492 t[k] = true; | |
| 493 end | |
| 494 elseif mapping.type == "func" and mapping.st2json then | 506 elseif mapping.type == "func" and mapping.st2json then |
| 495 local child = s:get_child(mapping.tagname, mapping.xmlns or k); | 507 t[mapping.key] = mapping.st2json(tag); |
| 496 -- TODO handle err | |
| 497 if child then | |
| 498 t[k] = mapping.st2json(child); | |
| 499 end | |
| 500 end | 508 end |
| 501 end | 509 end |
| 502 | 510 |
| 503 return t; | 511 return t; |
| 504 end | 512 end |