Software /
code /
prosody
Comparison
util/jsonschema.lua @ 12581:6ee9071c0a1f
Merge 0.12->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 08 Jul 2022 19:36:07 +0200 |
parent | 12579:ca6a43fe0231 |
child | 12759:ec54fe0003d5 |
comparison
equal
deleted
inserted
replaced
12578:10bb58ad5583 | 12581:6ee9071c0a1f |
---|---|
1 -- This file is generated from teal-src/util/jsonschema.lua | |
2 | |
1 local m_type = math.type or function (n) | 3 local m_type = math.type or function (n) |
2 return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; | 4 return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; |
3 end; | 5 end; |
4 local json = require("util.json") | 6 local json = require("util.json") |
5 local null = json.null; | 7 local null = json.null; |
8 | 10 |
9 local json_type_name = json.json_type_name | 11 local json_type_name = json.json_type_name |
10 | 12 |
11 local schema_t = {} | 13 local schema_t = {} |
12 | 14 |
13 local json_schema_object = {xml_t = {}} | 15 local json_schema_object = { xml_t = {} } |
14 | |
15 local type_validators = {} | |
16 | 16 |
17 local function simple_validate(schema, data) | 17 local function simple_validate(schema, data) |
18 if schema == "object" and type(data) == "table" then | 18 if schema == nil then |
19 return true | |
20 elseif schema == "object" and type(data) == "table" then | |
19 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "string") | 21 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "string") |
20 elseif schema == "array" and type(data) == "table" then | 22 elseif schema == "array" and type(data) == "table" then |
21 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "number") | 23 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "number") |
22 elseif schema == "integer" then | 24 elseif schema == "integer" then |
23 return m_type(data) == schema | 25 return m_type(data) == schema |
24 elseif schema == "null" then | 26 elseif schema == "null" then |
25 return data == null | 27 return data == null |
28 elseif type(schema) == "table" then | |
29 for _, one in ipairs(schema) do | |
30 if simple_validate(one, data) then | |
31 return true | |
32 end | |
33 end | |
34 return false | |
26 else | 35 else |
27 return type(data) == schema | 36 return type(data) == schema |
28 end | 37 end |
29 end | 38 end |
30 | 39 |
31 type_validators.string = function(schema, data) | 40 local complex_validate |
32 | |
33 if type(data) == "string" then | |
34 if schema.maxLength and #data > schema.maxLength then | |
35 return false | |
36 end | |
37 if schema.minLength and #data < schema.minLength then | |
38 return false | |
39 end | |
40 return true | |
41 end | |
42 return false | |
43 end | |
44 | |
45 type_validators.number = function(schema, data) | |
46 if schema.multipleOf and data % schema.multipleOf ~= 0 then | |
47 return false | |
48 end | |
49 | |
50 if schema.maximum and not (data <= schema.maximum) then | |
51 return false | |
52 end | |
53 | |
54 if schema.exclusiveMaximum and not (data < schema.exclusiveMaximum) then | |
55 return false | |
56 end | |
57 | |
58 if schema.minimum and not (data >= schema.minimum) then | |
59 return false | |
60 end | |
61 | |
62 if schema.exclusiveMinimum and not (data > schema.exclusiveMinimum) then | |
63 return false | |
64 end | |
65 | |
66 return true | |
67 end | |
68 | |
69 type_validators.integer = type_validators.number | |
70 | 41 |
71 local function validate(schema, data, root) | 42 local function validate(schema, data, root) |
72 if type(schema) == "boolean" then | 43 if type(schema) == "boolean" then |
73 return schema | 44 return schema |
74 end | 45 else |
75 if type(schema) == "string" then | 46 return complex_validate(schema, data, root) |
76 return simple_validate(schema, data) | 47 end |
77 end | 48 end |
78 if type(schema) == "table" then | 49 |
79 if root == nil then | 50 function complex_validate(schema, data, root) |
80 root = schema | 51 |
81 end | 52 if root == nil then |
82 if schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then | 53 root = schema |
83 local referenced = pointer.resolve(root, schema["$ref"]:sub(2)) | 54 end |
84 if referenced ~= nil then | 55 |
85 return validate(referenced, data, root) | 56 if schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then |
86 end | 57 local referenced = pointer.resolve(root, schema["$ref"]:sub(2)) |
87 end | 58 if referenced ~= nil and referenced ~= root and referenced ~= schema then |
88 | 59 if not validate(referenced, data, root) then |
89 if schema.allOf then | |
90 for _, sub in ipairs(schema.allOf) do | |
91 if not validate(sub, data, root) then | |
92 return false | |
93 end | |
94 end | |
95 return true | |
96 end | |
97 | |
98 if schema.oneOf then | |
99 local valid = 0 | |
100 for _, sub in ipairs(schema.oneOf) do | |
101 if validate(sub, data, root) then | |
102 valid = valid + 1 | |
103 end | |
104 end | |
105 return valid == 1 | |
106 end | |
107 | |
108 if schema.anyOf then | |
109 for _, sub in ipairs(schema.anyOf) do | |
110 if validate(sub, data, root) then | |
111 return true | |
112 end | |
113 end | |
114 return false | |
115 end | |
116 | |
117 if schema["not"] then | |
118 if validate(schema["not"], data, root) then | |
119 return false | 60 return false |
120 end | 61 end |
121 end | 62 end |
122 | 63 end |
123 if schema["if"] then | 64 |
124 if validate(schema["if"], data, root) then | 65 if not simple_validate(schema.type, data) then |
125 if schema["then"] then | 66 return false |
126 return validate(schema["then"], data, root) | 67 end |
127 end | 68 |
128 else | 69 if schema.type == "object" then |
129 if schema["else"] then | 70 if type(data) == "table" then |
130 return validate(schema["else"], data, root) | 71 |
131 end | 72 for k in pairs(data) do |
132 end | 73 if not (type(k) == "string") then |
133 end | 74 return false |
134 | 75 end |
135 if schema.const ~= nil and schema.const ~= data then | 76 end |
136 return false | 77 end |
137 end | 78 end |
138 | 79 |
139 if schema["enum"] ~= nil then | 80 if schema.type == "array" then |
140 for _, v in ipairs(schema["enum"]) do | 81 if type(data) == "table" then |
141 if v == data then | 82 |
142 return true | 83 for i in pairs(data) do |
143 end | 84 if not (math.type(i) == "integer") then |
144 end | 85 return false |
145 return false | 86 end |
146 end | 87 end |
147 | 88 end |
148 if schema.type then | 89 end |
149 if not simple_validate(schema.type, data) then | 90 |
91 if schema["enum"] ~= nil then | |
92 local match = false | |
93 for _, v in ipairs(schema["enum"]) do | |
94 if v == data then | |
95 | |
96 match = true | |
97 break | |
98 end | |
99 end | |
100 if not match then | |
101 return false | |
102 end | |
103 end | |
104 | |
105 if type(data) == "string" then | |
106 if schema.maxLength and #data > schema.maxLength then | |
107 return false | |
108 end | |
109 if schema.minLength and #data < schema.minLength then | |
110 return false | |
111 end | |
112 end | |
113 | |
114 if type(data) == "number" then | |
115 if schema.multipleOf and (data == 0 or data % schema.multipleOf ~= 0) then | |
116 return false | |
117 end | |
118 | |
119 if schema.maximum and not (data <= schema.maximum) then | |
120 return false | |
121 end | |
122 | |
123 if schema.exclusiveMaximum and not (data < schema.exclusiveMaximum) then | |
124 return false | |
125 end | |
126 | |
127 if schema.minimum and not (data >= schema.minimum) then | |
128 return false | |
129 end | |
130 | |
131 if schema.exclusiveMinimum and not (data > schema.exclusiveMinimum) then | |
132 return false | |
133 end | |
134 end | |
135 | |
136 if schema.allOf then | |
137 for _, sub in ipairs(schema.allOf) do | |
138 if not validate(sub, data, root) then | |
150 return false | 139 return false |
151 end | 140 end |
152 | 141 end |
153 local validator = type_validators[schema.type] | 142 end |
154 if validator then | 143 |
155 return validator(schema, data, root) | 144 if schema.oneOf then |
156 end | 145 local valid = 0 |
157 end | 146 for _, sub in ipairs(schema.oneOf) do |
158 return true | 147 if validate(sub, data, root) then |
159 end | 148 valid = valid + 1 |
160 end | 149 end |
161 | 150 end |
162 type_validators.table = function(schema, data, root) | 151 if valid ~= 1 then |
152 return false | |
153 end | |
154 end | |
155 | |
156 if schema.anyOf then | |
157 local match = false | |
158 for _, sub in ipairs(schema.anyOf) do | |
159 if validate(sub, data, root) then | |
160 match = true | |
161 break | |
162 end | |
163 end | |
164 if not match then | |
165 return false | |
166 end | |
167 end | |
168 | |
169 if schema["not"] then | |
170 if validate(schema["not"], data, root) then | |
171 return false | |
172 end | |
173 end | |
174 | |
175 if schema["if"] ~= nil then | |
176 if validate(schema["if"], data, root) then | |
177 if schema["then"] then | |
178 return validate(schema["then"], data, root) | |
179 end | |
180 else | |
181 if schema["else"] then | |
182 return validate(schema["else"], data, root) | |
183 end | |
184 end | |
185 end | |
186 | |
187 if schema.const ~= nil and schema.const ~= data then | |
188 return false | |
189 end | |
190 | |
163 if type(data) == "table" then | 191 if type(data) == "table" then |
164 | 192 |
165 if schema.maxItems and #data > schema.maxItems then | 193 if schema.maxItems and #data > schema.maxItems then |
166 return false | 194 return false |
167 end | 195 end |
176 return false | 204 return false |
177 end | 205 end |
178 end | 206 end |
179 end | 207 end |
180 | 208 |
209 if schema.propertyNames ~= nil then | |
210 for k in pairs(data) do | |
211 if not validate(schema.propertyNames, k, root) then | |
212 return false | |
213 end | |
214 end | |
215 end | |
216 | |
181 if schema.properties then | 217 if schema.properties then |
182 local additional = schema.additionalProperties or true | 218 for k, sub in pairs(schema.properties) do |
219 if data[k] ~= nil and not validate(sub, data[k], root) then | |
220 return false | |
221 end | |
222 end | |
223 end | |
224 | |
225 if schema.additionalProperties ~= nil then | |
183 for k, v in pairs(data) do | 226 for k, v in pairs(data) do |
184 if schema.propertyNames and not validate(schema.propertyNames, k, root) then | 227 if schema.properties == nil or schema.properties[k] == nil then |
185 return false | 228 if not validate(schema.additionalProperties, v, root) then |
186 end | 229 return false |
187 local s = schema.properties[k] or additional | 230 end |
188 if not validate(s, v, root) then | |
189 return false | |
190 end | |
191 end | |
192 elseif schema.additionalProperties then | |
193 for k, v in pairs(data) do | |
194 if schema.propertyNames and not validate(schema.propertyNames, k, root) then | |
195 return false | |
196 end | |
197 if not validate(schema.additionalProperties, v, root) then | |
198 return false | |
199 end | 231 end |
200 end | 232 end |
201 end | 233 end |
202 | 234 |
203 if schema.uniqueItems then | 235 if schema.uniqueItems then |
210 values[v] = true | 242 values[v] = true |
211 end | 243 end |
212 end | 244 end |
213 | 245 |
214 local p = 0 | 246 local p = 0 |
215 if schema.prefixItems then | 247 if schema.prefixItems ~= nil then |
216 for i, s in ipairs(schema.prefixItems) do | 248 for i, s in ipairs(schema.prefixItems) do |
217 if validate(s, data[i], root) then | 249 if data[i] == nil then |
250 break | |
251 elseif validate(s, data[i], root) then | |
218 p = i | 252 p = i |
219 else | 253 else |
220 return false | 254 return false |
221 end | 255 end |
222 end | 256 end |
223 end | 257 end |
224 | 258 |
225 if schema.items then | 259 if schema.items ~= nil then |
226 for i = p + 1, #data do | 260 for i = p + 1, #data do |
227 if not validate(schema.items, data[i], root) then | 261 if not validate(schema.items, data[i], root) then |
228 return false | 262 return false |
229 end | 263 end |
230 end | 264 end |
231 end | 265 end |
232 | 266 |
233 if schema.contains then | 267 if schema.contains ~= nil then |
234 local found = false | 268 local found = false |
235 for i = 1, #data do | 269 for i = 1, #data do |
236 if validate(schema.contains, data[i], root) then | 270 if validate(schema.contains, data[i], root) then |
237 found = true | 271 found = true |
238 break | 272 break |
240 end | 274 end |
241 if not found then | 275 if not found then |
242 return false | 276 return false |
243 end | 277 end |
244 end | 278 end |
245 | 279 end |
246 return true | 280 |
247 end | 281 return true |
248 return false | |
249 end | 282 end |
250 | 283 |
251 type_validators.object = function(schema, data, root) | |
252 if type(data) == "table" then | |
253 for k in pairs(data) do | |
254 if not (type(k) == "string") then | |
255 return false | |
256 end | |
257 end | |
258 | |
259 return type_validators.table(schema, data, root) | |
260 end | |
261 return false | |
262 end | |
263 | |
264 type_validators.array = function(schema, data, root) | |
265 if type(data) == "table" then | |
266 | |
267 for i in pairs(data) do | |
268 if not (type(i) == "number") then | |
269 return false | |
270 end | |
271 end | |
272 | |
273 return type_validators.table(schema, data, root) | |
274 end | |
275 return false | |
276 end | |
277 | |
278 json_schema_object.validate = validate; | 284 json_schema_object.validate = validate; |
279 | 285 |
280 return json_schema_object | 286 return json_schema_object |