Software /
code /
prosody
Comparison
teal-src/util/datamapper.tl @ 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 |
parent | 11453:f0037234b2e9 |
child | 11455:a5050e21ab08 |
comparison
equal
deleted
inserted
replaced
11453:f0037234b2e9 | 11454:1d9c1893cc5e |
---|---|
26 if s == "true" or s == "1" then | 26 if s == "true" or s == "1" then |
27 return true | 27 return true |
28 elseif s == "false" or s == "0" then | 28 elseif s == "false" or s == "0" then |
29 return false | 29 return false |
30 end | 30 end |
31 end | |
32 | |
33 local enum value_goes | |
34 "in_tag_name" | |
35 "in_text" | |
36 "in_text_tag" | |
37 "in_attribute" | |
38 "in_single_attribute" | |
39 "in_children" | |
31 end | 40 end |
32 | 41 |
33 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table | 42 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table |
34 local out : { string : any } = {} | 43 local out : { string : any } = {} |
35 if schema.properties then | 44 if schema.properties then |
36 for prop, propschema in pairs(schema.properties) do | 45 for prop, propschema in pairs(schema.properties) do |
37 -- TODO factor out, if it's generic enough | 46 -- TODO factor out, if it's generic enough |
38 local name = prop | 47 local name = prop |
39 local namespace = s.attr.xmlns; | 48 local namespace = s.attr.xmlns; |
40 local prefix : string = nil | 49 local prefix : string = nil |
41 local is_attribute = false | 50 local value_where : value_goes = "in_text_tag" |
42 local is_text = false | |
43 local name_is_value = false; | |
44 local single_attribute : string | 51 local single_attribute : string |
45 local enums : { any } | 52 local enums : { any } |
46 | 53 |
47 local proptype : js.schema_t.type_e | 54 local proptype : js.schema_t.type_e |
48 if propschema is js.schema_t then | 55 if propschema is js.schema_t then |
60 end | 67 end |
61 if propschema.xml.prefix then | 68 if propschema.xml.prefix then |
62 prefix = propschema.xml.prefix | 69 prefix = propschema.xml.prefix |
63 end | 70 end |
64 if propschema.xml.attribute then | 71 if propschema.xml.attribute then |
65 is_attribute = true | 72 value_where = "in_attribute" |
66 elseif propschema.xml.text then | 73 elseif propschema.xml.text then |
67 -- XXX Not yet in OpenAPI | 74 -- XXX Not yet in OpenAPI |
68 is_text = true | 75 value_where = "in_text" |
69 elseif propschema.xml.x_name_is_value then | 76 elseif propschema.xml.x_name_is_value then |
70 -- XXX Custom extension | 77 -- XXX Custom extension |
71 name_is_value = true | 78 value_where = "in_tag_name" |
72 elseif propschema.xml.x_single_attribute then | 79 elseif propschema.xml.x_single_attribute then |
73 -- XXX Custom extension | 80 -- XXX Custom extension |
74 single_attribute = propschema.xml.x_single_attribute | 81 single_attribute = propschema.xml.x_single_attribute |
82 value_where = "in_single_attribute" | |
75 end | 83 end |
76 if propschema["const"] then | 84 if propschema["const"] then |
77 enums = { propschema["const"] } | 85 enums = { propschema["const"] } |
78 elseif propschema["enum"] then | 86 elseif propschema["enum"] then |
79 enums = propschema["enum"] | 87 enums = propschema["enum"] |
80 end | 88 end |
81 end | 89 end |
82 | 90 |
83 if name_is_value then | 91 if value_where == "in_tag_name" then |
84 local c : st.stanza_t | 92 local c : st.stanza_t |
85 if proptype == "boolean" then | 93 if proptype == "boolean" then |
86 c = s:get_child(name, namespace); | 94 c = s:get_child(name, namespace); |
87 elseif enums and proptype == "string" then | 95 elseif enums and proptype == "string" then |
88 -- XXX O(n²) ? | 96 -- XXX O(n²) ? |
98 if c and proptype == "string" then | 106 if c and proptype == "string" then |
99 out[prop] = c.name; | 107 out[prop] = c.name; |
100 elseif proptype == "boolean" and c then | 108 elseif proptype == "boolean" and c then |
101 out[prop] = true; | 109 out[prop] = true; |
102 end | 110 end |
103 elseif is_attribute then | 111 elseif value_where == "in_attribute" then |
104 local attr = name | 112 local attr = name |
105 if prefix then | 113 if prefix then |
106 attr = prefix .. ':' .. name | 114 attr = prefix .. ':' .. name |
107 elseif namespace ~= s.attr.xmlns then | 115 elseif namespace ~= s.attr.xmlns then |
108 attr = namespace .. "\1" .. name | 116 attr = namespace .. "\1" .. name |
115 elseif proptype == "boolean" then | 123 elseif proptype == "boolean" then |
116 out[prop] = toboolean(s.attr[attr]) | 124 out[prop] = toboolean(s.attr[attr]) |
117 -- else TODO | 125 -- else TODO |
118 end | 126 end |
119 | 127 |
120 elseif is_text then | 128 elseif value_where == "in_text" then |
121 if proptype == "string" then | 129 if proptype == "string" then |
122 out[prop] = s:get_text() | 130 out[prop] = s:get_text() |
123 elseif proptype == "integer" or proptype == "number" then | 131 elseif proptype == "integer" or proptype == "number" then |
124 out[prop] = tonumber(s:get_text()) | 132 out[prop] = tonumber(s:get_text()) |
125 end | 133 end |
126 | 134 |
127 elseif single_attribute then | 135 elseif value_where == "in_single_attribute" then |
128 local c = s:get_child(name, namespace) | 136 local c = s:get_child(name, namespace) |
129 local a = c and c.attr[single_attribute] | 137 local a = c and c.attr[single_attribute] |
130 if proptype == "string" then | 138 if proptype == "string" then |
131 out[prop] = a | 139 out[prop] = a |
132 elseif proptype == "integer" or proptype == "number" then | 140 elseif proptype == "integer" or proptype == "number" then |
187 end | 195 end |
188 | 196 |
189 local name = prop | 197 local name = prop |
190 local namespace = current_ns | 198 local namespace = current_ns |
191 local prefix : string = nil | 199 local prefix : string = nil |
192 local is_attribute = false | 200 local value_where : value_goes = "in_text_tag" |
193 local is_text = false | |
194 local name_is_value = false; | |
195 local single_attribute : string | 201 local single_attribute : string |
196 | 202 |
197 if propschema is js.schema_t and propschema.xml then | 203 if propschema is js.schema_t and propschema.xml then |
198 | 204 |
199 if propschema.xml.name then | 205 if propschema.xml.name then |
206 if propschema.xml.prefix then | 212 if propschema.xml.prefix then |
207 prefix = propschema.xml.prefix | 213 prefix = propschema.xml.prefix |
208 end | 214 end |
209 | 215 |
210 if propschema.xml.attribute then | 216 if propschema.xml.attribute then |
211 is_attribute = true | 217 value_where = "in_attribute" |
212 elseif propschema.xml.text then | 218 elseif propschema.xml.text then |
213 is_text = true | 219 value_where = "in_text" |
214 elseif propschema.xml.x_name_is_value then | 220 elseif propschema.xml.x_name_is_value then |
215 name_is_value = true | 221 value_where = "in_tag_name" |
216 elseif propschema.xml.x_single_attribute then | 222 elseif propschema.xml.x_single_attribute then |
217 single_attribute = propschema.xml.x_single_attribute | 223 single_attribute = propschema.xml.x_single_attribute |
218 end | 224 value_where = "in_single_attribute" |
219 end | 225 end |
220 | 226 end |
221 if is_attribute then | 227 |
228 if value_where == "in_attribute" then | |
222 local attr = name | 229 local attr = name |
223 if prefix then | 230 if prefix then |
224 attr = prefix .. ':' .. name | 231 attr = prefix .. ':' .. name |
225 elseif namespace ~= current_ns then | 232 elseif namespace ~= current_ns then |
226 attr = namespace .. "\1" .. name | 233 attr = namespace .. "\1" .. name |
233 elseif proptype == "integer" and v is number then | 240 elseif proptype == "integer" and v is number then |
234 out.attr[attr] = string.format("%d", v) | 241 out.attr[attr] = string.format("%d", v) |
235 elseif proptype == "boolean" then | 242 elseif proptype == "boolean" then |
236 out.attr[attr] = v and "1" or "0" | 243 out.attr[attr] = v and "1" or "0" |
237 end | 244 end |
238 elseif is_text then | 245 elseif value_where == "in_text" then |
239 if v is string then | 246 if v is string then |
240 out:text(v) | 247 out:text(v) |
241 end | 248 end |
242 elseif single_attribute then | 249 elseif value_where == "in_single_attribute" then |
243 local propattr : { string : string } = {} | 250 local propattr : { string : string } = {} |
244 | 251 |
245 if namespace ~= current_ns then | 252 if namespace ~= current_ns then |
246 propattr.xmlns = namespace | 253 propattr.xmlns = namespace |
247 end | 254 end |
260 else | 267 else |
261 local propattr : { string : string } | 268 local propattr : { string : string } |
262 if namespace ~= current_ns then | 269 if namespace ~= current_ns then |
263 propattr = { xmlns = namespace } | 270 propattr = { xmlns = namespace } |
264 end | 271 end |
265 if name_is_value then | 272 if value_where == "in_tag_name" then |
266 if proptype == "string" and v is string then | 273 if proptype == "string" and v is string then |
267 out:tag(v, propattr):up(); | 274 out:tag(v, propattr):up(); |
268 elseif proptype == "boolean" and v == true then | 275 elseif proptype == "boolean" and v == true then |
269 out:tag(name, propattr):up(); | 276 out:tag(name, propattr):up(); |
270 end | 277 end |