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