Comparison

util/jsonschema.lua @ 11434:66d4067bdfb2

util.jsonschema: Library for JSON Schema validation
author Kim Alvefur <zash@zash.se>
date Sat, 06 Mar 2021 21:07:53 +0100
child 11440:d5288c99bb5a
comparison
equal deleted inserted replaced
11433:bef67691a713 11434:66d4067bdfb2
1 local schema_t = {xml_t = {}}
2
3 local type_e = schema_t.type_e
4
5 local type_validators = {}
6
7 local function simple_validate(schema, data)
8 if schema == "object" and type(data) == "table" then
9 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "string")
10 elseif schema == "array" and type(data) == "table" then
11 return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "number")
12 elseif schema == "integer" then
13 return math.type(data) == schema
14 else
15 return type(data) == schema
16 end
17 end
18
19 type_validators.string = function(schema, data)
20
21 if type(data) == "string" then
22 if schema.maxLength and #data > schema.maxLength then
23 return false
24 end
25 if schema.minLength and #data < schema.minLength then
26 return false
27 end
28 return true
29 end
30 return false
31 end
32
33 type_validators.number = function(schema, data)
34 if schema.multipleOf and data % schema.multipleOf ~= 0 then
35 return false
36 end
37
38 if schema.maximum and not (data <= schema.maximum) then
39 return false
40 end
41
42 if schema.exclusiveMaximum and not (data < schema.exclusiveMaximum) then
43 return false
44 end
45
46 if schema.minimum and not (data >= schema.minimum) then
47 return false
48 end
49
50 if schema.exclusiveMinimum and not (data > schema.exclusiveMinimum) then
51 return false
52 end
53
54 return true
55 end
56
57 type_validators.integer = type_validators.number
58
59 local function validate(schema, data)
60 if type(schema) == "string" then
61 return simple_validate(schema, data)
62 end
63 if type(schema) == "table" then
64 if schema.allOf then
65 for _, sub in ipairs(schema.allOf) do
66 if not validate(sub, data) then
67 return false
68 end
69 end
70 return true
71 end
72
73 if schema.oneOf then
74 local valid = 0
75 for _, sub in ipairs(schema.oneOf) do
76 if validate(sub, data) then
77 valid = valid + 1
78 end
79 end
80 return valid == 1
81 end
82
83 if schema.anyOf then
84 for _, sub in ipairs(schema.anyOf) do
85 if validate(sub, data) then
86 return true
87 end
88 end
89 return false
90 end
91
92 if schema["not"] then
93 if validate(schema["not"], data) then
94 return false
95 end
96 end
97
98 if schema["if"] then
99 if validate(schema["if"], data) then
100 if schema["then"] then
101 return validate(schema["then"], data)
102 end
103 else
104 if schema["else"] then
105 return validate(schema["else"], data)
106 end
107 end
108 end
109
110 if not simple_validate(schema.type, data) then
111 return false
112 end
113
114 if schema.const ~= nil and schema.const ~= data then
115 return false
116 end
117
118 if schema.enum ~= nil then
119 for _, v in ipairs(schema.enum) do
120 if v == data then
121 return true
122 end
123 end
124 return false
125 end
126
127 local validator = type_validators[schema.type]
128 if not validator then
129 return true
130 end
131
132 return validator(schema, data)
133 end
134 end
135
136 type_validators.table = function(schema, data)
137 if type(data) == "table" then
138
139 if schema.maxItems and #data > schema.maxItems then
140 return false
141 end
142
143 if schema.minItems and #data < schema.minItems then
144 return false
145 end
146
147 if schema.required then
148 for _, k in ipairs(schema.required) do
149 if data[k] == nil then
150 return false
151 end
152 end
153 end
154
155 if schema.properties then
156 for k, s in pairs(schema.properties) do
157 if data[k] ~= nil then
158 if not validate(s, data[k]) then
159 return false
160 end
161 end
162 end
163 end
164
165 if schema.additionalProperties then
166 for k, v in pairs(data) do
167 if type(k) == "string" then
168 if not (schema.properties and schema.properties[k]) then
169 if not validate(schema.additionalProperties, v) then
170 return false
171 end
172 end
173 end
174 end
175 elseif schema.properties then
176 for k in pairs(data) do
177 if type(k) == "string" then
178 if schema.properties[k] == nil then
179 return false
180 end
181 end
182 end
183 end
184
185 if schema.uniqueItems then
186
187 local values = {}
188 for _, v in pairs(data) do
189 if values[v] then
190 return false
191 end
192 values[v] = true
193 end
194 return true
195 end
196
197 local item_schemas = schema.items
198 if item_schemas and item_schemas[1] == nil then
199 local item_schema = item_schemas
200 for i, v in pairs(data) do
201 if type(i) == "number" then
202 if not validate(item_schema, v) then
203 return false
204 end
205 end
206 end
207 elseif item_schemas and item_schemas[1] ~= nil then
208 for i, s in ipairs(item_schemas) do
209 validate(s, data[i])
210 end
211 end
212
213 return true
214 end
215 return false
216 end
217
218 type_validators.object = function(schema, data)
219 if type(data) == "table" then
220 for k in pairs(data) do
221 if not (type(k) == "string") then
222 return false
223 end
224 end
225
226 return type_validators.table(schema, data)
227 end
228 return false
229 end
230
231 type_validators.array = function(schema, data)
232 if type(data) == "table" then
233
234 for i in pairs(data) do
235 if not (type(i) == "number") then
236 return false
237 end
238 end
239
240 return type_validators.table(schema, data)
241 end
242 return false
243 end
244
245 return {validate = validate; schema_t = schema_t}