Software /
code /
prosody
Comparison
teal-src/util/datamapper.tl @ 11435:a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Based on the XML support in the OpenAPI specification.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 07 Mar 2021 00:57:36 +0100 |
child | 11436:5df9ffc25bb4 |
comparison
equal
deleted
inserted
replaced
11434:66d4067bdfb2 | 11435:a1fa6202fa13 |
---|---|
1 local st = require "util.stanza"; | |
2 local js = require "util.jsonschema" | |
3 | |
4 local function toboolean ( s : string ) : boolean | |
5 if s == "true" or s == "1" then | |
6 return true | |
7 elseif s == "false" or s == "0" then | |
8 return false | |
9 end | |
10 end | |
11 | |
12 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table | |
13 local out : { string : any } = {} | |
14 if schema.properties then | |
15 for prop, propschema in pairs(schema.properties) do | |
16 -- TODO factor out, if it's generic enough | |
17 local name = prop | |
18 local namespace = s.attr.xmlns; | |
19 local prefix : string = nil | |
20 local is_attribute = false | |
21 local is_text = false | |
22 | |
23 local proptype : js.schema_t.type_e | |
24 if propschema is js.schema_t then | |
25 proptype = propschema.type | |
26 elseif propschema is js.schema_t.type_e then | |
27 proptype = propschema | |
28 end | |
29 | |
30 if propschema is js.schema_t and propschema.xml then | |
31 if propschema.xml.name then | |
32 name = propschema.xml.name | |
33 end | |
34 if propschema.xml.namespace then | |
35 namespace = propschema.xml.namespace | |
36 end | |
37 if propschema.xml.prefix then | |
38 prefix = propschema.xml.prefix | |
39 end | |
40 if propschema.xml.attribute then | |
41 is_attribute = true | |
42 elseif propschema.xml.text then | |
43 is_text = true | |
44 end | |
45 end | |
46 | |
47 if is_attribute then | |
48 local attr = name | |
49 if prefix then | |
50 attr = prefix .. ':' .. name | |
51 elseif namespace ~= s.attr.xmlns then | |
52 attr = namespace .. "\1" .. name | |
53 end | |
54 if proptype == "string" then | |
55 out[prop] = s.attr[attr] | |
56 elseif proptype == "integer" or proptype == "number" then | |
57 -- TODO floor if integer ? | |
58 out[prop] = tonumber(s.attr[attr]) | |
59 elseif proptype == "boolean" then | |
60 out[prop] = toboolean(s.attr[attr]) | |
61 -- else TODO | |
62 end | |
63 | |
64 elseif is_text then | |
65 if proptype == "string" then | |
66 out[prop] = s:get_text() | |
67 elseif proptype == "integer" or proptype == "number" then | |
68 out[prop] = tonumber(s:get_text()) | |
69 end | |
70 | |
71 else | |
72 | |
73 if proptype == "string" then | |
74 out[prop] = s:get_child_text(name, namespace) | |
75 elseif proptype == "integer" or proptype == "number" then | |
76 out[prop] = tonumber(s:get_child_text(name, namespace)) | |
77 elseif proptype == "object" and propschema is js.schema_t then | |
78 local c = s:get_child(name, namespace) | |
79 if c then | |
80 out[prop] = parse_object(propschema, c); | |
81 end | |
82 -- else TODO | |
83 end | |
84 end | |
85 end | |
86 end | |
87 | |
88 return out | |
89 end | |
90 | |
91 local function parse (schema : js.schema_t, s : st.stanza_t) : table | |
92 if schema.type == "object" then | |
93 return parse_object(schema, s) | |
94 end | |
95 end | |
96 | |
97 return { | |
98 parse = parse, | |
99 -- unparse = unparse, -- TODO | |
100 } |