Comparison

util/datamapper.lua @ 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
6 elseif s == "false" or s == "0" then 6 elseif s == "false" or s == "0" then
7 return false 7 return false
8 end 8 end
9 end 9 end
10 10
11 local value_goes = {}
12
11 local function parse_object(schema, s) 13 local function parse_object(schema, s)
12 local out = {} 14 local out = {}
13 if schema.properties then 15 if schema.properties then
14 for prop, propschema in pairs(schema.properties) do 16 for prop, propschema in pairs(schema.properties) do
15 17
16 local name = prop 18 local name = prop
17 local namespace = s.attr.xmlns; 19 local namespace = s.attr.xmlns;
18 local prefix = nil 20 local prefix = nil
19 local is_attribute = false 21 local value_where = "in_text_tag"
20 local is_text = false
21 local name_is_value = false;
22 local single_attribute 22 local single_attribute
23 local enums 23 local enums
24 24
25 local proptype 25 local proptype
26 if type(propschema) == "table" then 26 if type(propschema) == "table" then
38 end 38 end
39 if propschema.xml.prefix then 39 if propschema.xml.prefix then
40 prefix = propschema.xml.prefix 40 prefix = propschema.xml.prefix
41 end 41 end
42 if propschema.xml.attribute then 42 if propschema.xml.attribute then
43 is_attribute = true 43 value_where = "in_attribute"
44 elseif propschema.xml.text then 44 elseif propschema.xml.text then
45 45
46 is_text = true 46 value_where = "in_text"
47 elseif propschema.xml.x_name_is_value then 47 elseif propschema.xml.x_name_is_value then
48 48
49 name_is_value = true 49 value_where = "in_tag_name"
50 elseif propschema.xml.x_single_attribute then 50 elseif propschema.xml.x_single_attribute then
51 51
52 single_attribute = propschema.xml.x_single_attribute 52 single_attribute = propschema.xml.x_single_attribute
53 value_where = "in_single_attribute"
53 end 54 end
54 if propschema["const"] then 55 if propschema["const"] then
55 enums = {propschema["const"]} 56 enums = {propschema["const"]}
56 elseif propschema["enum"] then 57 elseif propschema["enum"] then
57 enums = propschema["enum"] 58 enums = propschema["enum"]
58 end 59 end
59 end 60 end
60 61
61 if name_is_value then 62 if value_where == "in_tag_name" then
62 local c 63 local c
63 if proptype == "boolean" then 64 if proptype == "boolean" then
64 c = s:get_child(name, namespace); 65 c = s:get_child(name, namespace);
65 elseif enums and proptype == "string" then 66 elseif enums and proptype == "string" then
66 67
76 if c and proptype == "string" then 77 if c and proptype == "string" then
77 out[prop] = c.name; 78 out[prop] = c.name;
78 elseif proptype == "boolean" and c then 79 elseif proptype == "boolean" and c then
79 out[prop] = true; 80 out[prop] = true;
80 end 81 end
81 elseif is_attribute then 82 elseif value_where == "in_attribute" then
82 local attr = name 83 local attr = name
83 if prefix then 84 if prefix then
84 attr = prefix .. ":" .. name 85 attr = prefix .. ":" .. name
85 elseif namespace ~= s.attr.xmlns then 86 elseif namespace ~= s.attr.xmlns then
86 attr = namespace .. "\1" .. name 87 attr = namespace .. "\1" .. name
93 elseif proptype == "boolean" then 94 elseif proptype == "boolean" then
94 out[prop] = toboolean(s.attr[attr]) 95 out[prop] = toboolean(s.attr[attr])
95 96
96 end 97 end
97 98
98 elseif is_text then 99 elseif value_where == "in_text" then
99 if proptype == "string" then 100 if proptype == "string" then
100 out[prop] = s:get_text() 101 out[prop] = s:get_text()
101 elseif proptype == "integer" or proptype == "number" then 102 elseif proptype == "integer" or proptype == "number" then
102 out[prop] = tonumber(s:get_text()) 103 out[prop] = tonumber(s:get_text())
103 end 104 end
104 105
105 elseif single_attribute then 106 elseif value_where == "in_single_attribute" then
106 local c = s:get_child(name, namespace) 107 local c = s:get_child(name, namespace)
107 local a = c and c.attr[single_attribute] 108 local a = c and c.attr[single_attribute]
108 if proptype == "string" then 109 if proptype == "string" then
109 out[prop] = a 110 out[prop] = a
110 elseif proptype == "integer" or proptype == "number" then 111 elseif proptype == "integer" or proptype == "number" then
165 end 166 end
166 167
167 local name = prop 168 local name = prop
168 local namespace = current_ns 169 local namespace = current_ns
169 local prefix = nil 170 local prefix = nil
170 local is_attribute = false 171 local value_where = "in_text_tag"
171 local is_text = false
172 local name_is_value = false;
173 local single_attribute 172 local single_attribute
174 173
175 if type(propschema) == "table" and propschema.xml then 174 if type(propschema) == "table" and propschema.xml then
176 175
177 if propschema.xml.name then 176 if propschema.xml.name then
184 if propschema.xml.prefix then 183 if propschema.xml.prefix then
185 prefix = propschema.xml.prefix 184 prefix = propschema.xml.prefix
186 end 185 end
187 186
188 if propschema.xml.attribute then 187 if propschema.xml.attribute then
189 is_attribute = true 188 value_where = "in_attribute"
190 elseif propschema.xml.text then 189 elseif propschema.xml.text then
191 is_text = true 190 value_where = "in_text"
192 elseif propschema.xml.x_name_is_value then 191 elseif propschema.xml.x_name_is_value then
193 name_is_value = true 192 value_where = "in_tag_name"
194 elseif propschema.xml.x_single_attribute then 193 elseif propschema.xml.x_single_attribute then
195 single_attribute = propschema.xml.x_single_attribute 194 single_attribute = propschema.xml.x_single_attribute
196 end 195 value_where = "in_single_attribute"
197 end 196 end
198 197 end
199 if is_attribute then 198
199 if value_where == "in_attribute" then
200 local attr = name 200 local attr = name
201 if prefix then 201 if prefix then
202 attr = prefix .. ":" .. name 202 attr = prefix .. ":" .. name
203 elseif namespace ~= current_ns then 203 elseif namespace ~= current_ns then
204 attr = namespace .. "\1" .. name 204 attr = namespace .. "\1" .. name
211 elseif proptype == "integer" and type(v) == "number" then 211 elseif proptype == "integer" and type(v) == "number" then
212 out.attr[attr] = string.format("%d", v) 212 out.attr[attr] = string.format("%d", v)
213 elseif proptype == "boolean" then 213 elseif proptype == "boolean" then
214 out.attr[attr] = v and "1" or "0" 214 out.attr[attr] = v and "1" or "0"
215 end 215 end
216 elseif is_text then 216 elseif value_where == "in_text" then
217 if type(v) == "string" then 217 if type(v) == "string" then
218 out:text(v) 218 out:text(v)
219 end 219 end
220 elseif single_attribute then 220 elseif value_where == "in_single_attribute" then
221 local propattr = {} 221 local propattr = {}
222 222
223 if namespace ~= current_ns then 223 if namespace ~= current_ns then
224 propattr.xmlns = namespace 224 propattr.xmlns = namespace
225 end 225 end
238 else 238 else
239 local propattr 239 local propattr
240 if namespace ~= current_ns then 240 if namespace ~= current_ns then
241 propattr = {xmlns = namespace} 241 propattr = {xmlns = namespace}
242 end 242 end
243 if name_is_value then 243 if value_where == "in_tag_name" then
244 if proptype == "string" and type(v) == "string" then 244 if proptype == "string" and type(v) == "string" then
245 out:tag(v, propattr):up(); 245 out:tag(v, propattr):up();
246 elseif proptype == "boolean" and v == true then 246 elseif proptype == "boolean" and v == true then
247 out:tag(name, propattr):up(); 247 out:tag(name, propattr):up();
248 end 248 end