Software /
code /
prosody
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 |