Comparison

teal-src/util/datamapper.tl @ 11456:4e376a43fe40

util.datamapper: Factor out common schema unpacking This code extracts the bits from the schema that determines how the data is to be mapped to/from XML.
author Kim Alvefur <zash@zash.se>
date Sun, 14 Mar 2021 16:50:49 +0100
parent 11455:a5050e21ab08
child 11457:6a51749af7f4
comparison
equal deleted inserted replaced
11455:a5050e21ab08 11456:4e376a43fe40
49 "in_attribute" 49 "in_attribute"
50 "in_single_attribute" 50 "in_single_attribute"
51 "in_children" 51 "in_children"
52 end 52 end
53 53
54 local function unpack_propschema( propschema : js.schema_t | js.schema_t.type_e, propname : string, current_ns : string )
55 : js.schema_t.type_e, value_goes, string, string, string, string, { any }
56 local proptype : js.schema_t.type_e = "string"
57 local value_where : value_goes = "in_text_tag"
58 local name = propname
59 local namespace = current_ns
60 local prefix : string
61 local single_attribute : string
62 local enums : { any }
63
64 if propschema is js.schema_t then
65 proptype = propschema.type
66 elseif propschema is js.schema_t.type_e then
67 proptype = propschema
68 end
69
70 if propschema is js.schema_t then
71 local xml = propschema.xml
72 if xml then
73 if xml.name then
74 name = xml.name
75 end
76 if xml.namespace then
77 namespace = xml.namespace
78 end
79 if xml.prefix then
80 prefix = xml.prefix
81 end
82
83 if xml.attribute then
84 value_where = "in_attribute"
85 elseif xml.text then
86 value_where = "in_text"
87 elseif xml.x_name_is_value then
88 value_where = "in_tag_name"
89 elseif xml.x_single_attribute then
90 single_attribute = xml.x_single_attribute
91 value_where = "in_single_attribute"
92 end
93 end
94 if propschema["const"] then
95 enums = { propschema["const"] }
96 elseif propschema["enum"] then
97 enums = propschema["enum"]
98 end
99 end
100
101 if proptype == "object" or proptype == "array" then
102 value_where = "in_children"
103 end
104
105 return proptype, value_where, name, namespace, prefix, single_attribute, enums
106 end
107
108
54 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table 109 local function parse_object (schema : js.schema_t, s : st.stanza_t) : table
55 local out : { string : any } = {} 110 local out : { string : any } = {}
56 if schema.properties then 111 if schema.properties then
57 for prop, propschema in pairs(schema.properties) do 112 for prop, propschema in pairs(schema.properties) do
58 -- TODO factor out, if it's generic enough 113
59 local name = prop 114 local proptype, value_where, name, namespace, prefix, single_attribute, enums = unpack_propschema(propschema, prop, s.attr.xmlns)
60 local namespace = s.attr.xmlns;
61 local prefix : string = nil
62 local value_where : value_goes = "in_text_tag"
63 local single_attribute : string
64 local enums : { any }
65
66 local proptype : js.schema_t.type_e
67 if propschema is js.schema_t then
68 proptype = propschema.type
69 elseif propschema is js.schema_t.type_e then
70 proptype = propschema
71 end
72
73 if proptype == "object" or proptype == "array" then
74 value_where = "in_children"
75 end
76
77 if propschema is js.schema_t and propschema.xml then
78 if propschema.xml.name then
79 name = propschema.xml.name
80 end
81 if propschema.xml.namespace then
82 namespace = propschema.xml.namespace
83 end
84 if propschema.xml.prefix then
85 prefix = propschema.xml.prefix
86 end
87 if propschema.xml.attribute then
88 value_where = "in_attribute"
89 elseif propschema.xml.text then
90 -- XXX Not yet in OpenAPI
91 value_where = "in_text"
92 elseif propschema.xml.x_name_is_value then
93 -- XXX Custom extension
94 value_where = "in_tag_name"
95 elseif propschema.xml.x_single_attribute then
96 -- XXX Custom extension
97 single_attribute = propschema.xml.x_single_attribute
98 value_where = "in_single_attribute"
99 end
100 if propschema["const"] then
101 enums = { propschema["const"] }
102 elseif propschema["enum"] then
103 enums = propschema["enum"]
104 end
105 end
106 115
107 local value : string 116 local value : string
108 if value_where == "in_tag_name" then 117 if value_where == "in_tag_name" then
109 local c : st.stanza_t 118 local c : st.stanza_t
110 if proptype == "boolean" then 119 if proptype == "boolean" then
179 188
180 for prop, propschema in pairs(schema.properties) do 189 for prop, propschema in pairs(schema.properties) do
181 local v = t[prop] 190 local v = t[prop]
182 191
183 if v ~= nil then 192 if v ~= nil then
184 local proptype : js.schema_t.type_e 193
185 if propschema is js.schema_t then 194 local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(propschema, prop, current_ns)
186 proptype = propschema.type
187 elseif propschema is js.schema_t.type_e then
188 proptype = propschema
189 end
190
191 local name = prop
192 local namespace = current_ns
193 local prefix : string = nil
194 local value_where : value_goes = "in_text_tag"
195 local single_attribute : string
196
197 if propschema is js.schema_t and propschema.xml then
198
199 if propschema.xml.name then
200 name = propschema.xml.name
201 end
202 if propschema.xml.namespace then
203 namespace = propschema.xml.namespace
204 end
205
206 if propschema.xml.prefix then
207 prefix = propschema.xml.prefix
208 end
209
210 if propschema.xml.attribute then
211 value_where = "in_attribute"
212 elseif propschema.xml.text then
213 value_where = "in_text"
214 elseif propschema.xml.x_name_is_value then
215 value_where = "in_tag_name"
216 elseif propschema.xml.x_single_attribute then
217 single_attribute = propschema.xml.x_single_attribute
218 value_where = "in_single_attribute"
219 end
220 end
221 195
222 if value_where == "in_attribute" then 196 if value_where == "in_attribute" then
223 local attr = name 197 local attr = name
224 if prefix then 198 if prefix then
225 attr = prefix .. ':' .. name 199 attr = prefix .. ':' .. name