Comparison

teal-src/util/datamapper.tl @ 11455:a5050e21ab08

util.datamapper: Separate extraction of xml from coercion to target type Now it gets the text, attribute or name first, then turns it into whatever the schema wants. This should be easier to further factor out into preparation for array support.
author Kim Alvefur <zash@zash.se>
date Sun, 14 Mar 2021 03:06:37 +0100
parent 11454:1d9c1893cc5e
child 11456:4e376a43fe40
comparison
equal deleted inserted replaced
11454:1d9c1893cc5e 11455:a5050e21ab08
25 local function toboolean ( s : string ) : boolean 25 local function toboolean ( s : string ) : boolean
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 elseif s then
31 return true
32 end
33 end
34
35 local function totype(t : js.schema_t.type_e, s : string) : any
36 if t == "string" then
37 return s;
38 elseif t == "boolean" then
39 return toboolean(s)
40 elseif t == "number" or t == "integer" then
41 return tonumber(s)
30 end 42 end
31 end 43 end
32 44
33 local enum value_goes 45 local enum value_goes
34 "in_tag_name" 46 "in_tag_name"
54 local proptype : js.schema_t.type_e 66 local proptype : js.schema_t.type_e
55 if propschema is js.schema_t then 67 if propschema is js.schema_t then
56 proptype = propschema.type 68 proptype = propschema.type
57 elseif propschema is js.schema_t.type_e then 69 elseif propschema is js.schema_t.type_e then
58 proptype = propschema 70 proptype = propschema
71 end
72
73 if proptype == "object" or proptype == "array" then
74 value_where = "in_children"
59 end 75 end
60 76
61 if propschema is js.schema_t and propschema.xml then 77 if propschema is js.schema_t and propschema.xml then
62 if propschema.xml.name then 78 if propschema.xml.name then
63 name = propschema.xml.name 79 name = propschema.xml.name
86 elseif propschema["enum"] then 102 elseif propschema["enum"] then
87 enums = propschema["enum"] 103 enums = propschema["enum"]
88 end 104 end
89 end 105 end
90 106
107 local value : string
91 if value_where == "in_tag_name" then 108 if value_where == "in_tag_name" then
92 local c : st.stanza_t 109 local c : st.stanza_t
93 if proptype == "boolean" then 110 if proptype == "boolean" then
94 c = s:get_child(name, namespace); 111 c = s:get_child(name, namespace);
95 elseif enums and proptype == "string" then 112 elseif enums and proptype == "string" then
101 if c then break end 118 if c then break end
102 end 119 end
103 else 120 else
104 c = s:get_child(nil, namespace); 121 c = s:get_child(nil, namespace);
105 end 122 end
106 if c and proptype == "string" then 123 value = c.name;
107 out[prop] = c.name;
108 elseif proptype == "boolean" and c then
109 out[prop] = true;
110 end
111 elseif value_where == "in_attribute" then 124 elseif value_where == "in_attribute" then
112 local attr = name 125 local attr = name
113 if prefix then 126 if prefix then
114 attr = prefix .. ':' .. name 127 attr = prefix .. ':' .. name
115 elseif namespace ~= s.attr.xmlns then 128 elseif namespace ~= s.attr.xmlns then
116 attr = namespace .. "\1" .. name 129 attr = namespace .. "\1" .. name
117 end 130 end
118 if proptype == "string" then 131 value = s.attr[attr]
119 out[prop] = s.attr[attr]
120 elseif proptype == "integer" or proptype == "number" then
121 -- TODO floor if integer ?
122 out[prop] = tonumber(s.attr[attr])
123 elseif proptype == "boolean" then
124 out[prop] = toboolean(s.attr[attr])
125 -- else TODO
126 end
127 132
128 elseif value_where == "in_text" then 133 elseif value_where == "in_text" then
129 if proptype == "string" then 134 value = s:get_text()
130 out[prop] = s:get_text()
131 elseif proptype == "integer" or proptype == "number" then
132 out[prop] = tonumber(s:get_text())
133 end
134 135
135 elseif value_where == "in_single_attribute" then 136 elseif value_where == "in_single_attribute" then
136 local c = s:get_child(name, namespace) 137 local c = s:get_child(name, namespace)
137 local a = c and c.attr[single_attribute] 138 value = c and c.attr[single_attribute]
138 if proptype == "string" then 139 elseif value_where == "in_text_tag" then
139 out[prop] = a 140 value = s:get_child_text(name, namespace)
140 elseif proptype == "integer" or proptype == "number" then 141 elseif value_where == "in_children" and propschema is js.schema_t then
141 out[prop] = tonumber(a) 142 if proptype == "object" then
142 elseif proptype == "boolean" then
143 out[prop] = toboolean(a)
144 end
145 else
146
147 if proptype == "string" then
148 out[prop] = s:get_child_text(name, namespace)
149 elseif proptype == "integer" or proptype == "number" then
150 out[prop] = tonumber(s:get_child_text(name, namespace))
151 elseif proptype == "object" and propschema is js.schema_t then
152 local c = s:get_child(name, namespace) 143 local c = s:get_child(name, namespace)
153 if c then 144 if c then
154 out[prop] = parse_object(propschema, c); 145 out[prop] = parse_object(propschema, c);
155 end 146 end
156 -- else TODO 147 -- else TODO
157 end 148 end
149 end
150 if value_where ~= "in_children" then
151 out[prop] = totype(proptype, value)
158 end 152 end
159 end 153 end
160 end 154 end
161 155
162 return out 156 return out