fast_json-schema 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Dockerfile +17 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +68 -0
- data/LICENSE.txt +21 -0
- data/README.md +156 -0
- data/Rakefile +60 -0
- data/build-deps +3 -0
- data/data/invalid.json +31 -0
- data/data/schema.json +150 -0
- data/data/valid.json +49 -0
- data/ext/fast_json/schema/all_of.c +23 -0
- data/ext/fast_json/schema/all_of.h +4 -0
- data/ext/fast_json/schema/any_of.c +22 -0
- data/ext/fast_json/schema/any_of.h +4 -0
- data/ext/fast_json/schema/compiled_schema.c +503 -0
- data/ext/fast_json/schema/compiled_schema.h +10 -0
- data/ext/fast_json/schema/context.c +78 -0
- data/ext/fast_json/schema/error.c +26 -0
- data/ext/fast_json/schema/error.h +5 -0
- data/ext/fast_json/schema/extconf.rb +7 -0
- data/ext/fast_json/schema/formats/custom_format.c +63 -0
- data/ext/fast_json/schema/formats/custom_format.h +4 -0
- data/ext/fast_json/schema/formats/date.c +48 -0
- data/ext/fast_json/schema/formats/date.h +5 -0
- data/ext/fast_json/schema/formats/date_time.c +22 -0
- data/ext/fast_json/schema/formats/date_time.h +4 -0
- data/ext/fast_json/schema/formats/email.c +8 -0
- data/ext/fast_json/schema/formats/email.h +4 -0
- data/ext/fast_json/schema/formats/format.c +68 -0
- data/ext/fast_json/schema/formats/format.h +4 -0
- data/ext/fast_json/schema/formats/hostname.c +8 -0
- data/ext/fast_json/schema/formats/hostname.h +4 -0
- data/ext/fast_json/schema/formats/idn_email.c +8 -0
- data/ext/fast_json/schema/formats/idn_email.h +4 -0
- data/ext/fast_json/schema/formats/idn_hostname.c +8 -0
- data/ext/fast_json/schema/formats/idn_hostname.h +4 -0
- data/ext/fast_json/schema/formats/ipv4.c +8 -0
- data/ext/fast_json/schema/formats/ipv4.h +4 -0
- data/ext/fast_json/schema/formats/ipv6.c +8 -0
- data/ext/fast_json/schema/formats/ipv6.h +4 -0
- data/ext/fast_json/schema/formats/iri.c +8 -0
- data/ext/fast_json/schema/formats/iri.h +4 -0
- data/ext/fast_json/schema/formats/iri_reference.c +8 -0
- data/ext/fast_json/schema/formats/iri_reference.h +4 -0
- data/ext/fast_json/schema/formats/json_pointer.c +8 -0
- data/ext/fast_json/schema/formats/json_pointer.h +4 -0
- data/ext/fast_json/schema/formats/regex.c +27 -0
- data/ext/fast_json/schema/formats/regex.h +4 -0
- data/ext/fast_json/schema/formats/relative_json_pointer.c +57 -0
- data/ext/fast_json/schema/formats/relative_json_pointer.h +4 -0
- data/ext/fast_json/schema/formats/time.c +65 -0
- data/ext/fast_json/schema/formats/time.h +5 -0
- data/ext/fast_json/schema/formats/uri.c +8 -0
- data/ext/fast_json/schema/formats/uri.h +4 -0
- data/ext/fast_json/schema/formats/uri_reference.c +8 -0
- data/ext/fast_json/schema/formats/uri_reference.h +4 -0
- data/ext/fast_json/schema/formats/uri_template.c +8 -0
- data/ext/fast_json/schema/formats/uri_template.h +4 -0
- data/ext/fast_json/schema/formats/utils/addr_spec_parser.c +342 -0
- data/ext/fast_json/schema/formats/utils/addr_spec_parser.h +16 -0
- data/ext/fast_json/schema/formats/utils/hostname_parser.c +113 -0
- data/ext/fast_json/schema/formats/utils/hostname_parser.h +17 -0
- data/ext/fast_json/schema/formats/utils/ip_parser.c +126 -0
- data/ext/fast_json/schema/formats/utils/ip_parser.h +25 -0
- data/ext/fast_json/schema/formats/utils/json_pointer_parser.c +45 -0
- data/ext/fast_json/schema/formats/utils/json_pointer_parser.h +20 -0
- data/ext/fast_json/schema/formats/utils/uri_parser.c +605 -0
- data/ext/fast_json/schema/formats/utils/uri_parser.h +20 -0
- data/ext/fast_json/schema/formats/utils/uri_template_parser.c +235 -0
- data/ext/fast_json/schema/formats/utils/uri_template_parser.h +18 -0
- data/ext/fast_json/schema/formats/utils/utf8.c +73 -0
- data/ext/fast_json/schema/formats/utils/utf8.h +17 -0
- data/ext/fast_json/schema/if.c +31 -0
- data/ext/fast_json/schema/if.h +4 -0
- data/ext/fast_json/schema/is_valid.c +124 -0
- data/ext/fast_json/schema/is_valid.h +6 -0
- data/ext/fast_json/schema/keywords.c +220 -0
- data/ext/fast_json/schema/keywords.h +60 -0
- data/ext/fast_json/schema/nested_schemas.c +68 -0
- data/ext/fast_json/schema/nested_schemas.h +4 -0
- data/ext/fast_json/schema/not.c +11 -0
- data/ext/fast_json/schema/not.h +4 -0
- data/ext/fast_json/schema/one_of.c +23 -0
- data/ext/fast_json/schema/one_of.h +4 -0
- data/ext/fast_json/schema/path.c +44 -0
- data/ext/fast_json/schema/path.h +5 -0
- data/ext/fast_json/schema/properties_val.c +103 -0
- data/ext/fast_json/schema/properties_val.h +6 -0
- data/ext/fast_json/schema/ref.c +7 -0
- data/ext/fast_json/schema/ref.h +4 -0
- data/ext/fast_json/schema/ref_resolver.c +85 -0
- data/ext/fast_json/schema/ref_resolver.h +5 -0
- data/ext/fast_json/schema/schema.c +68 -0
- data/ext/fast_json/schema/schema_collection.c +29 -0
- data/ext/fast_json/schema/schema_collection.h +3 -0
- data/ext/fast_json/schema/types/compiled_schema.h +96 -0
- data/ext/fast_json/schema/types/context.h +27 -0
- data/ext/fast_json/schema/validate.c +63 -0
- data/ext/fast_json/schema/validate.h +19 -0
- data/ext/fast_json/schema/validate_array.c +130 -0
- data/ext/fast_json/schema/validate_array.h +4 -0
- data/ext/fast_json/schema/validate_bool.c +7 -0
- data/ext/fast_json/schema/validate_bool.h +4 -0
- data/ext/fast_json/schema/validate_integer.c +52 -0
- data/ext/fast_json/schema/validate_integer.h +4 -0
- data/ext/fast_json/schema/validate_null.c +7 -0
- data/ext/fast_json/schema/validate_null.h +4 -0
- data/ext/fast_json/schema/validate_number.c +62 -0
- data/ext/fast_json/schema/validate_number.h +4 -0
- data/ext/fast_json/schema/validate_object.c +159 -0
- data/ext/fast_json/schema/validate_object.h +4 -0
- data/ext/fast_json/schema/validate_string.c +32 -0
- data/ext/fast_json/schema/validate_string.h +4 -0
- data/ext/fast_json/schema/value_pointer_caster.h +9 -0
- data/fast_json-schema.gemspec +31 -0
- data/lib/fast_json/schema/error.rb +16 -0
- data/lib/fast_json/schema/version.rb +7 -0
- data/lib/fast_json/schema.rb +50 -0
- data/makefile +10 -0
- metadata +164 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#include "keywords.h"
|
|
2
|
+
|
|
3
|
+
VALUE root_path_str;
|
|
4
|
+
|
|
5
|
+
VALUE id_str,
|
|
6
|
+
ref_str,
|
|
7
|
+
recursiveAnchor_str,
|
|
8
|
+
recursiveRef_str;
|
|
9
|
+
|
|
10
|
+
VALUE type_str,
|
|
11
|
+
const_str,
|
|
12
|
+
enum_str;
|
|
13
|
+
|
|
14
|
+
VALUE if_str,
|
|
15
|
+
then_str,
|
|
16
|
+
else_str,
|
|
17
|
+
allOf_str,
|
|
18
|
+
anyOf_str,
|
|
19
|
+
oneOf_str,
|
|
20
|
+
not_str;
|
|
21
|
+
|
|
22
|
+
// Integer and Number keywords
|
|
23
|
+
VALUE multipleOf_str,
|
|
24
|
+
maximum_str,
|
|
25
|
+
exclusiveMaximum_str,
|
|
26
|
+
minimum_str,
|
|
27
|
+
exclusiveMinimum_str;
|
|
28
|
+
|
|
29
|
+
// String keywords
|
|
30
|
+
VALUE maxLength_str,
|
|
31
|
+
minLength_str,
|
|
32
|
+
pattern_str,
|
|
33
|
+
format_str;
|
|
34
|
+
|
|
35
|
+
// Array keywords
|
|
36
|
+
VALUE items_str,
|
|
37
|
+
additionalItems_str,
|
|
38
|
+
unevaluatedItems_str,
|
|
39
|
+
contains_str,
|
|
40
|
+
maxItems_str,
|
|
41
|
+
minItems_str,
|
|
42
|
+
uniqueItems_str,
|
|
43
|
+
maxContains_str,
|
|
44
|
+
minContains_str;
|
|
45
|
+
|
|
46
|
+
// Object keywords
|
|
47
|
+
VALUE properties_str,
|
|
48
|
+
patternProperties_str,
|
|
49
|
+
additionalProperties_str,
|
|
50
|
+
unevaluatedProperties_str,
|
|
51
|
+
propertyNames_str,
|
|
52
|
+
maxProperties_str,
|
|
53
|
+
minProperties_str,
|
|
54
|
+
required_str,
|
|
55
|
+
dependentRequired_str,
|
|
56
|
+
dependencies_str;
|
|
57
|
+
|
|
58
|
+
VALUE object_str;
|
|
59
|
+
|
|
60
|
+
VALUE known_keywords_hash;
|
|
61
|
+
|
|
62
|
+
bool is_known_keyword(VALUE key) {
|
|
63
|
+
if(!RB_TYPE_P(key, T_STRING)) return false;
|
|
64
|
+
|
|
65
|
+
return rb_hash_lookup(known_keywords_hash, key) != Qnil;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void Init_keywords() {
|
|
69
|
+
root_path_str = rb_str_new_literal("#");
|
|
70
|
+
|
|
71
|
+
id_str = rb_str_new_literal("$id");
|
|
72
|
+
ref_str = rb_str_new_literal("$ref");
|
|
73
|
+
recursiveAnchor_str = rb_str_new_literal("$recursiveAnchor");
|
|
74
|
+
recursiveRef_str = rb_str_new_literal("$recursiveRef");
|
|
75
|
+
|
|
76
|
+
type_str = rb_str_new_literal("type");
|
|
77
|
+
const_str = rb_str_new_literal("const");
|
|
78
|
+
enum_str = rb_str_new_literal("enum");
|
|
79
|
+
|
|
80
|
+
if_str = rb_str_new_literal("if");
|
|
81
|
+
then_str = rb_str_new_literal("then");
|
|
82
|
+
else_str = rb_str_new_literal("else");
|
|
83
|
+
allOf_str = rb_str_new_literal("allOf");
|
|
84
|
+
anyOf_str = rb_str_new_literal("anyOf");
|
|
85
|
+
oneOf_str = rb_str_new_literal("oneOf");
|
|
86
|
+
not_str = rb_str_new_literal("not");
|
|
87
|
+
|
|
88
|
+
multipleOf_str = rb_str_new_literal("multipleOf");
|
|
89
|
+
maximum_str = rb_str_new_literal("maximum");
|
|
90
|
+
exclusiveMaximum_str = rb_str_new_literal("exclusiveMaximum");
|
|
91
|
+
minimum_str = rb_str_new_literal("minimum");
|
|
92
|
+
exclusiveMinimum_str = rb_str_new_literal("exclusiveMinimum");
|
|
93
|
+
|
|
94
|
+
maxLength_str = rb_str_new_literal("maxLength");
|
|
95
|
+
minLength_str = rb_str_new_literal("minLength");
|
|
96
|
+
pattern_str = rb_str_new_literal("pattern");
|
|
97
|
+
format_str = rb_str_new_literal("format");
|
|
98
|
+
|
|
99
|
+
items_str = rb_str_new_literal("items");
|
|
100
|
+
additionalItems_str = rb_str_new_literal("additionalItems");
|
|
101
|
+
unevaluatedItems_str = rb_str_new_literal("unevaluatedItems");
|
|
102
|
+
contains_str = rb_str_new_literal("contains");
|
|
103
|
+
maxItems_str = rb_str_new_literal("maxItems");
|
|
104
|
+
minItems_str = rb_str_new_literal("minItems");
|
|
105
|
+
uniqueItems_str = rb_str_new_literal("uniqueItems");
|
|
106
|
+
maxContains_str = rb_str_new_literal("maxContains");
|
|
107
|
+
minContains_str = rb_str_new_literal("minContains");
|
|
108
|
+
|
|
109
|
+
properties_str = rb_str_new_literal("properties");
|
|
110
|
+
patternProperties_str = rb_str_new_literal("patternProperties");
|
|
111
|
+
additionalProperties_str = rb_str_new_literal("additionalProperties");
|
|
112
|
+
unevaluatedProperties_str = rb_str_new_literal("unevaluatedProperties");
|
|
113
|
+
propertyNames_str = rb_str_new_literal("propertyNames");
|
|
114
|
+
maxProperties_str = rb_str_new_literal("maxProperties");
|
|
115
|
+
minProperties_str = rb_str_new_literal("minProperties");
|
|
116
|
+
required_str = rb_str_new_literal("required");
|
|
117
|
+
dependentRequired_str = rb_str_new_literal("dependentRequired");
|
|
118
|
+
dependencies_str = rb_str_new_literal("dependencies");
|
|
119
|
+
|
|
120
|
+
object_str = rb_str_new_literal("object");
|
|
121
|
+
|
|
122
|
+
known_keywords_hash = rb_hash_new();
|
|
123
|
+
rb_hash_aset(known_keywords_hash, id_str, Qtrue);
|
|
124
|
+
rb_hash_aset(known_keywords_hash, ref_str, Qtrue);
|
|
125
|
+
rb_hash_aset(known_keywords_hash, recursiveAnchor_str, Qtrue);
|
|
126
|
+
rb_hash_aset(known_keywords_hash, recursiveRef_str, Qtrue);
|
|
127
|
+
rb_hash_aset(known_keywords_hash, type_str, Qtrue);
|
|
128
|
+
rb_hash_aset(known_keywords_hash, const_str, Qtrue);
|
|
129
|
+
rb_hash_aset(known_keywords_hash, enum_str, Qtrue);
|
|
130
|
+
rb_hash_aset(known_keywords_hash, if_str, Qtrue);
|
|
131
|
+
rb_hash_aset(known_keywords_hash, then_str, Qtrue);
|
|
132
|
+
rb_hash_aset(known_keywords_hash, else_str, Qtrue);
|
|
133
|
+
rb_hash_aset(known_keywords_hash, allOf_str, Qtrue);
|
|
134
|
+
rb_hash_aset(known_keywords_hash, anyOf_str, Qtrue);
|
|
135
|
+
rb_hash_aset(known_keywords_hash, oneOf_str, Qtrue);
|
|
136
|
+
rb_hash_aset(known_keywords_hash, not_str, Qtrue);
|
|
137
|
+
rb_hash_aset(known_keywords_hash, multipleOf_str, Qtrue);
|
|
138
|
+
rb_hash_aset(known_keywords_hash, maximum_str, Qtrue);
|
|
139
|
+
rb_hash_aset(known_keywords_hash, exclusiveMaximum_str, Qtrue);
|
|
140
|
+
rb_hash_aset(known_keywords_hash, minimum_str, Qtrue);
|
|
141
|
+
rb_hash_aset(known_keywords_hash, exclusiveMinimum_str, Qtrue);
|
|
142
|
+
rb_hash_aset(known_keywords_hash, maxLength_str, Qtrue);
|
|
143
|
+
rb_hash_aset(known_keywords_hash, minLength_str, Qtrue);
|
|
144
|
+
rb_hash_aset(known_keywords_hash, pattern_str, Qtrue);
|
|
145
|
+
rb_hash_aset(known_keywords_hash, format_str, Qtrue);
|
|
146
|
+
rb_hash_aset(known_keywords_hash, items_str, Qtrue);
|
|
147
|
+
rb_hash_aset(known_keywords_hash, additionalItems_str, Qtrue);
|
|
148
|
+
rb_hash_aset(known_keywords_hash, unevaluatedItems_str, Qtrue);
|
|
149
|
+
rb_hash_aset(known_keywords_hash, contains_str, Qtrue);
|
|
150
|
+
rb_hash_aset(known_keywords_hash, maxItems_str, Qtrue);
|
|
151
|
+
rb_hash_aset(known_keywords_hash, minItems_str, Qtrue);
|
|
152
|
+
rb_hash_aset(known_keywords_hash, uniqueItems_str, Qtrue);
|
|
153
|
+
rb_hash_aset(known_keywords_hash, maxContains_str, Qtrue);
|
|
154
|
+
rb_hash_aset(known_keywords_hash, minContains_str, Qtrue);
|
|
155
|
+
rb_hash_aset(known_keywords_hash, properties_str, Qtrue);
|
|
156
|
+
rb_hash_aset(known_keywords_hash, patternProperties_str, Qtrue);
|
|
157
|
+
rb_hash_aset(known_keywords_hash, additionalProperties_str, Qtrue);
|
|
158
|
+
rb_hash_aset(known_keywords_hash, unevaluatedProperties_str, Qtrue);
|
|
159
|
+
rb_hash_aset(known_keywords_hash, propertyNames_str, Qtrue);
|
|
160
|
+
rb_hash_aset(known_keywords_hash, maxProperties_str, Qtrue);
|
|
161
|
+
rb_hash_aset(known_keywords_hash, minProperties_str, Qtrue);
|
|
162
|
+
rb_hash_aset(known_keywords_hash, required_str, Qtrue);
|
|
163
|
+
rb_hash_aset(known_keywords_hash, dependentRequired_str, Qtrue);
|
|
164
|
+
rb_hash_aset(known_keywords_hash, dependencies_str, Qtrue);
|
|
165
|
+
|
|
166
|
+
rb_gc_register_address(&known_keywords_hash);
|
|
167
|
+
|
|
168
|
+
rb_gc_register_address(&root_path_str);
|
|
169
|
+
|
|
170
|
+
rb_gc_register_address(&id_str);
|
|
171
|
+
rb_gc_register_address(&ref_str);
|
|
172
|
+
rb_gc_register_address(&recursiveAnchor_str);
|
|
173
|
+
rb_gc_register_address(&recursiveRef_str);
|
|
174
|
+
|
|
175
|
+
rb_gc_register_address(&type_str);
|
|
176
|
+
rb_gc_register_address(&const_str);
|
|
177
|
+
rb_gc_register_address(&enum_str);
|
|
178
|
+
|
|
179
|
+
rb_gc_register_address(&if_str);
|
|
180
|
+
rb_gc_register_address(&then_str);
|
|
181
|
+
rb_gc_register_address(&else_str);
|
|
182
|
+
rb_gc_register_address(&allOf_str);
|
|
183
|
+
rb_gc_register_address(&anyOf_str);
|
|
184
|
+
rb_gc_register_address(&oneOf_str);
|
|
185
|
+
rb_gc_register_address(¬_str);
|
|
186
|
+
|
|
187
|
+
rb_gc_register_address(&multipleOf_str);
|
|
188
|
+
rb_gc_register_address(&maximum_str);
|
|
189
|
+
rb_gc_register_address(&exclusiveMaximum_str);
|
|
190
|
+
rb_gc_register_address(&minimum_str);
|
|
191
|
+
rb_gc_register_address(&exclusiveMinimum_str);
|
|
192
|
+
|
|
193
|
+
rb_gc_register_address(&maxLength_str);
|
|
194
|
+
rb_gc_register_address(&minLength_str);
|
|
195
|
+
rb_gc_register_address(&pattern_str);
|
|
196
|
+
rb_gc_register_address(&format_str);
|
|
197
|
+
|
|
198
|
+
rb_gc_register_address(&items_str);
|
|
199
|
+
rb_gc_register_address(&additionalItems_str);
|
|
200
|
+
rb_gc_register_address(&unevaluatedItems_str);
|
|
201
|
+
rb_gc_register_address(&contains_str);
|
|
202
|
+
rb_gc_register_address(&maxItems_str);
|
|
203
|
+
rb_gc_register_address(&minItems_str);
|
|
204
|
+
rb_gc_register_address(&uniqueItems_str);
|
|
205
|
+
rb_gc_register_address(&maxContains_str);
|
|
206
|
+
rb_gc_register_address(&minContains_str);
|
|
207
|
+
|
|
208
|
+
rb_gc_register_address(&properties_str);
|
|
209
|
+
rb_gc_register_address(&patternProperties_str);
|
|
210
|
+
rb_gc_register_address(&additionalProperties_str);
|
|
211
|
+
rb_gc_register_address(&unevaluatedProperties_str);
|
|
212
|
+
rb_gc_register_address(&propertyNames_str);
|
|
213
|
+
rb_gc_register_address(&maxProperties_str);
|
|
214
|
+
rb_gc_register_address(&minProperties_str);
|
|
215
|
+
rb_gc_register_address(&required_str);
|
|
216
|
+
rb_gc_register_address(&dependentRequired_str);
|
|
217
|
+
rb_gc_register_address(&dependencies_str);
|
|
218
|
+
|
|
219
|
+
rb_gc_register_address(&object_str);
|
|
220
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
|
|
3
|
+
extern VALUE root_path_str;
|
|
4
|
+
|
|
5
|
+
extern VALUE id_str,
|
|
6
|
+
ref_str,
|
|
7
|
+
recursiveAnchor_str,
|
|
8
|
+
recursiveRef_str;
|
|
9
|
+
|
|
10
|
+
extern VALUE type_str,
|
|
11
|
+
const_str,
|
|
12
|
+
enum_str;
|
|
13
|
+
|
|
14
|
+
extern VALUE if_str,
|
|
15
|
+
then_str,
|
|
16
|
+
else_str,
|
|
17
|
+
allOf_str,
|
|
18
|
+
anyOf_str,
|
|
19
|
+
oneOf_str,
|
|
20
|
+
not_str;
|
|
21
|
+
|
|
22
|
+
extern VALUE multipleOf_str,
|
|
23
|
+
maximum_str,
|
|
24
|
+
exclusiveMaximum_str,
|
|
25
|
+
minimum_str,
|
|
26
|
+
exclusiveMinimum_str;
|
|
27
|
+
|
|
28
|
+
extern VALUE maxLength_str,
|
|
29
|
+
minLength_str,
|
|
30
|
+
pattern_str,
|
|
31
|
+
format_str;
|
|
32
|
+
|
|
33
|
+
extern VALUE items_str,
|
|
34
|
+
additionalItems_str,
|
|
35
|
+
unevaluatedItems_str,
|
|
36
|
+
contains_str,
|
|
37
|
+
maxItems_str,
|
|
38
|
+
minItems_str,
|
|
39
|
+
uniqueItems_str,
|
|
40
|
+
maxContains_str,
|
|
41
|
+
minContains_str;
|
|
42
|
+
|
|
43
|
+
extern VALUE properties_str,
|
|
44
|
+
patternProperties_str,
|
|
45
|
+
additionalProperties_str,
|
|
46
|
+
unevaluatedProperties_str,
|
|
47
|
+
propertyNames_str,
|
|
48
|
+
maxProperties_str,
|
|
49
|
+
minProperties_str,
|
|
50
|
+
required_str,
|
|
51
|
+
dependentRequired_str,
|
|
52
|
+
dependencies_str;
|
|
53
|
+
|
|
54
|
+
extern VALUE object_str;
|
|
55
|
+
|
|
56
|
+
extern VALUE known_keywords_hash;
|
|
57
|
+
|
|
58
|
+
bool is_known_keyword(VALUE);
|
|
59
|
+
|
|
60
|
+
void Init_keywords();
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#include "nested_schemas.h"
|
|
2
|
+
#include "keywords.h"
|
|
3
|
+
#include "path.h"
|
|
4
|
+
|
|
5
|
+
extern CompiledSchema *create_compiled_schema(VALUE, schema_flag_t);
|
|
6
|
+
extern void compile(CompiledSchema *, VALUE, VALUE, VALUE);
|
|
7
|
+
|
|
8
|
+
static bool is_schema_shaped(VALUE value) {
|
|
9
|
+
return RB_TYPE_P(value, T_HASH) ||
|
|
10
|
+
RB_TYPE_P(value, T_TRUE) ||
|
|
11
|
+
RB_TYPE_P(value, T_FALSE);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static int count_nested(VALUE key, VALUE value, VALUE data) {
|
|
15
|
+
if(!RB_TYPE_P(key, T_STRING)) return ST_CONTINUE;
|
|
16
|
+
if(is_known_keyword(key)) return ST_CONTINUE;
|
|
17
|
+
if(!is_schema_shaped(value)) return ST_CONTINUE;
|
|
18
|
+
|
|
19
|
+
size_t *count = (size_t *)data;
|
|
20
|
+
(*count)++;
|
|
21
|
+
|
|
22
|
+
return ST_CONTINUE;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
struct compile_memo_S {
|
|
26
|
+
CompiledSchema *root_schema;
|
|
27
|
+
VALUE ref_data;
|
|
28
|
+
VALUE custom_formats;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
static int compile_nested(VALUE key, VALUE value, VALUE data) {
|
|
32
|
+
if(!RB_TYPE_P(key, T_STRING)) return ST_CONTINUE;
|
|
33
|
+
if(is_known_keyword(key)) return ST_CONTINUE;
|
|
34
|
+
if(!is_schema_shaped(value)) return ST_CONTINUE;
|
|
35
|
+
|
|
36
|
+
struct compile_memo_S *memo = (struct compile_memo_S *)data;
|
|
37
|
+
|
|
38
|
+
VALUE child_path = new_path(memo->root_schema->path, key);
|
|
39
|
+
|
|
40
|
+
CompiledSchema *child = create_compiled_schema(child_path, NO_FLAG);
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* Append the child pointer to the parent's nested_schemas array and bump the
|
|
44
|
+
* count BEFORE running `compile` on the child, so the parent's mark function
|
|
45
|
+
* will reach this child if the GC fires during its compilation.
|
|
46
|
+
*/
|
|
47
|
+
memo->root_schema->nested_schemas[memo->root_schema->nested_schemas_count++] = child;
|
|
48
|
+
|
|
49
|
+
compile(child, value, memo->ref_data, memo->custom_formats);
|
|
50
|
+
|
|
51
|
+
return ST_CONTINUE;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void compile_nested_schemas(CompiledSchema *root_schema, VALUE ruby_schema, VALUE ref_data, VALUE custom_formats) {
|
|
55
|
+
if(!RB_TYPE_P(ruby_schema, T_HASH)) return;
|
|
56
|
+
|
|
57
|
+
size_t total = 0;
|
|
58
|
+
rb_hash_foreach(ruby_schema, count_nested, (VALUE)&total);
|
|
59
|
+
|
|
60
|
+
if(total == 0) return;
|
|
61
|
+
|
|
62
|
+
root_schema->nested_schemas = ALLOC_N(CompiledSchema *, total);
|
|
63
|
+
root_schema->nested_schemas_count = 0;
|
|
64
|
+
|
|
65
|
+
struct compile_memo_S memo = { root_schema, ref_data, custom_formats };
|
|
66
|
+
|
|
67
|
+
rb_hash_foreach(ruby_schema, compile_nested, (VALUE)&memo);
|
|
68
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#include "not.h"
|
|
2
|
+
#include "error.h"
|
|
3
|
+
|
|
4
|
+
extern bool is_valid(VALUE, CompiledSchema *, VALUE, Context *);
|
|
5
|
+
|
|
6
|
+
void validate_not(VALUE schema, CompiledSchema *compiled_schema, VALUE data, Context *context) {
|
|
7
|
+
bool valid = is_valid(schema, compiled_schema->not_schema, data, context);
|
|
8
|
+
|
|
9
|
+
if(valid)
|
|
10
|
+
yield_error(compiled_schema->not_schema, data, context, "not");
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#include "one_of.h"
|
|
2
|
+
#include "error.h"
|
|
3
|
+
|
|
4
|
+
extern bool is_valid(VALUE, CompiledSchema *, VALUE, Context *);
|
|
5
|
+
|
|
6
|
+
void validate_one_of(VALUE schema, CompiledSchema *compiled_schema, VALUE data, Context *context) {
|
|
7
|
+
long i, valid_count = 0;
|
|
8
|
+
|
|
9
|
+
for(i = 0; i < RARRAY_LEN(compiled_schema->oneOf_val); i++) {
|
|
10
|
+
VALUE child_compiled_schema_obj = rb_ary_entry(compiled_schema->oneOf_val, i);
|
|
11
|
+
|
|
12
|
+
CompiledSchema *child_compiled_schema;
|
|
13
|
+
GetCompiledSchema(child_compiled_schema_obj, child_compiled_schema);
|
|
14
|
+
|
|
15
|
+
bool valid = is_valid(schema, child_compiled_schema, data, context);
|
|
16
|
+
|
|
17
|
+
if(valid && ++valid_count > 1)
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if(valid_count != 1)
|
|
22
|
+
yield_error(compiled_schema, data, context, "oneOf");
|
|
23
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#include "path.h"
|
|
2
|
+
|
|
3
|
+
VALUE new_path(VALUE root, VALUE name) {
|
|
4
|
+
StringValue(root);
|
|
5
|
+
StringValue(name);
|
|
6
|
+
|
|
7
|
+
VALUE result = rb_str_dup(root);
|
|
8
|
+
|
|
9
|
+
rb_str_cat_cstr(result, "/");
|
|
10
|
+
rb_str_buf_append(result, name);
|
|
11
|
+
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
VALUE to_path(VALUE *list, int depth) {
|
|
16
|
+
int i;
|
|
17
|
+
VALUE path = rb_str_new2("");
|
|
18
|
+
|
|
19
|
+
for(i = 0; i <= depth; i++) {
|
|
20
|
+
if(RB_TYPE_P(list[i], T_STRING)) {
|
|
21
|
+
rb_str_append(path, list[i]);
|
|
22
|
+
} else if (RB_INTEGER_TYPE_P(list[i])) {
|
|
23
|
+
VALUE str = rb_sprintf("%ld", NUM2LONG(list[i]));
|
|
24
|
+
|
|
25
|
+
rb_str_append(path, str);
|
|
26
|
+
} else {
|
|
27
|
+
rb_raise(rb_eRuntimeError, "Unexpected value while generating the path!");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
rb_str_cat_cstr(path, "/");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return path;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
VALUE append_long_to_path(VALUE root, long i) {
|
|
37
|
+
StringValue(root);
|
|
38
|
+
|
|
39
|
+
VALUE result = rb_str_dup(root);
|
|
40
|
+
VALUE suffix = rb_sprintf("/%ld", i);
|
|
41
|
+
rb_str_buf_append(result, suffix);
|
|
42
|
+
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#include "properties_val.h"
|
|
2
|
+
#include "keywords.h"
|
|
3
|
+
#include "path.h"
|
|
4
|
+
#include "compiled_schema.h"
|
|
5
|
+
|
|
6
|
+
extern CompiledSchema *create_compiled_schema(VALUE, schema_flag_t);
|
|
7
|
+
extern void compile(CompiledSchema *, VALUE, VALUE, VALUE);
|
|
8
|
+
|
|
9
|
+
typedef VALUE (*key_transform_function)(VALUE);
|
|
10
|
+
|
|
11
|
+
struct memo_S {
|
|
12
|
+
VALUE properties_hash;
|
|
13
|
+
VALUE ref_data;
|
|
14
|
+
VALUE path;
|
|
15
|
+
VALUE custom_formats;
|
|
16
|
+
key_transform_function key_transform_function;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
VALUE no_op_key_transform(VALUE key) {
|
|
20
|
+
return key;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
VALUE regexp_key_transform(VALUE key) {
|
|
24
|
+
return rb_reg_new_str(key, 0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static int compile_property(VALUE key, VALUE value, VALUE data) {
|
|
28
|
+
if(!RB_TYPE_P(key, T_STRING)) return ST_CONTINUE;
|
|
29
|
+
|
|
30
|
+
struct memo_S *memo = (struct memo_S*)(data);
|
|
31
|
+
|
|
32
|
+
VALUE path = new_path(memo->path, key);
|
|
33
|
+
|
|
34
|
+
CompiledSchema *compiled_schema = create_compiled_schema(path, EXPOSE_TO_RUBY);
|
|
35
|
+
VALUE compiled_schema_obj = WrapCompiledSchema(compiled_schema);
|
|
36
|
+
|
|
37
|
+
compile(compiled_schema, value, memo->ref_data, memo->custom_formats);
|
|
38
|
+
|
|
39
|
+
rb_hash_aset(memo->properties_hash, memo->key_transform_function(key), compiled_schema_obj);
|
|
40
|
+
|
|
41
|
+
return ST_CONTINUE;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static VALUE compile_properties(CompiledSchema *root_schema, VALUE ruby_schema, VALUE ref_data, VALUE custom_formats, VALUE keyword, key_transform_function func) {
|
|
45
|
+
VALUE properties = rb_hash_aref(ruby_schema, keyword);
|
|
46
|
+
|
|
47
|
+
if(!RB_TYPE_P(properties, T_HASH)) return Qundef;
|
|
48
|
+
|
|
49
|
+
VALUE properties_hash = rb_hash_new();
|
|
50
|
+
VALUE properties_path = new_path(root_schema->path, keyword);
|
|
51
|
+
|
|
52
|
+
struct memo_S memo = { properties_hash, ref_data, properties_path, custom_formats, func };
|
|
53
|
+
|
|
54
|
+
rb_hash_foreach(properties, compile_property, (VALUE)&memo);
|
|
55
|
+
|
|
56
|
+
return properties_hash;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void compile_properties_val(CompiledSchema *root_schema, VALUE ruby_schema, VALUE ref_data, VALUE custom_formats) {
|
|
60
|
+
root_schema->properties_val = compile_properties(root_schema, ruby_schema, ref_data, custom_formats, properties_str, no_op_key_transform);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void compile_pattern_properties_val(CompiledSchema *root_schema, VALUE ruby_schema, VALUE ref_data, VALUE custom_formats) {
|
|
64
|
+
root_schema->patternProperties_val = compile_properties(root_schema, ruby_schema, ref_data, custom_formats, patternProperties_str, regexp_key_transform);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static int compile_dependency(VALUE key, VALUE value, VALUE data) {
|
|
68
|
+
if(!RB_TYPE_P(key, T_STRING)) return ST_CONTINUE;
|
|
69
|
+
|
|
70
|
+
if(RB_TYPE_P(value, T_ARRAY)) {
|
|
71
|
+
/*
|
|
72
|
+
* If the value is an array, we are creating a temporary Ruby hash and compiling it as
|
|
73
|
+
* if it was provided by the user which looks something like the following;
|
|
74
|
+
*
|
|
75
|
+
* { "type" => "object", "required" => ["foo", "bar"] }
|
|
76
|
+
*/
|
|
77
|
+
VALUE tmp_schema = rb_hash_new();
|
|
78
|
+
|
|
79
|
+
rb_hash_aset(tmp_schema, required_str, value);
|
|
80
|
+
rb_hash_aset(tmp_schema, type_str, object_str);
|
|
81
|
+
|
|
82
|
+
compile_property(key, tmp_schema, data);
|
|
83
|
+
} else {
|
|
84
|
+
compile_property(key, value, data);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return ST_CONTINUE;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void compile_dependencies_val(CompiledSchema *root_schema, VALUE ruby_schema, VALUE ref_data, VALUE custom_formats) {
|
|
91
|
+
VALUE dependencies = rb_hash_aref(ruby_schema, dependencies_str);
|
|
92
|
+
|
|
93
|
+
if(!RB_TYPE_P(dependencies, T_HASH)) return;
|
|
94
|
+
|
|
95
|
+
VALUE dependencies_val = rb_hash_new();
|
|
96
|
+
VALUE dependencies_path = new_path(root_schema->path, dependencies_str);
|
|
97
|
+
|
|
98
|
+
struct memo_S memo = { dependencies_val, ref_data, dependencies_path, custom_formats, no_op_key_transform };
|
|
99
|
+
|
|
100
|
+
rb_hash_foreach(dependencies, compile_dependency, (VALUE)&memo);
|
|
101
|
+
|
|
102
|
+
root_schema->dependencies_val = dependencies_val;
|
|
103
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include "types/compiled_schema.h"
|
|
3
|
+
|
|
4
|
+
void compile_properties_val(CompiledSchema *, VALUE, VALUE, VALUE);
|
|
5
|
+
void compile_pattern_properties_val(CompiledSchema *, VALUE, VALUE, VALUE);
|
|
6
|
+
void compile_dependencies_val(CompiledSchema *, VALUE, VALUE, VALUE);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#include "ref_resolver.h"
|
|
2
|
+
#include "value_pointer_caster.h"
|
|
3
|
+
|
|
4
|
+
static int resolve_refs_in_hash(VALUE key, VALUE value, VALUE data) {
|
|
5
|
+
CompiledSchema *child;
|
|
6
|
+
GetCompiledSchema(value, child);
|
|
7
|
+
|
|
8
|
+
resolve_refs(child, data);
|
|
9
|
+
|
|
10
|
+
return ST_CONTINUE;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static void resolve_refs_for_nested_schemas(CompiledSchema **children, size_t count, VALUE ref_data) {
|
|
14
|
+
for(size_t i = 0; i < count; i++)
|
|
15
|
+
resolve_refs(children[i], ref_data);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static void resolve_refs_in_array(VALUE array, VALUE ref_data) {
|
|
19
|
+
long i;
|
|
20
|
+
|
|
21
|
+
for(i = 0; i < RARRAY_LEN(array); i++) {
|
|
22
|
+
VALUE child_obj = rb_ary_entry(array, i);
|
|
23
|
+
|
|
24
|
+
CompiledSchema *child;
|
|
25
|
+
GetCompiledSchema(child_obj, child);
|
|
26
|
+
|
|
27
|
+
resolve_refs(child, ref_data);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void resolve_refs(CompiledSchema *compiled_schema, VALUE ref_data) {
|
|
32
|
+
if(compiled_schema == NULL) return;
|
|
33
|
+
|
|
34
|
+
if(compiled_schema->ref_val != Qundef) {
|
|
35
|
+
VALUE ref_schema_ptr = rb_hash_lookup(ref_data, compiled_schema->ref_val);
|
|
36
|
+
|
|
37
|
+
if(NIL_P(ref_schema_ptr))
|
|
38
|
+
rb_raise(rb_eRuntimeError, "Unresolved $ref: %s", StringValueCStr(compiled_schema->ref_val));
|
|
39
|
+
|
|
40
|
+
compiled_schema->ref_schema = (CompiledSchema *)NUM2PTR(ref_schema_ptr);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
resolve_refs(compiled_schema->if_schema, ref_data);
|
|
44
|
+
resolve_refs(compiled_schema->then_schema, ref_data);
|
|
45
|
+
resolve_refs(compiled_schema->else_schema, ref_data);
|
|
46
|
+
resolve_refs(compiled_schema->not_schema, ref_data);
|
|
47
|
+
resolve_refs(compiled_schema->items_schema, ref_data);
|
|
48
|
+
resolve_refs(compiled_schema->additionalItems_schema, ref_data);
|
|
49
|
+
resolve_refs(compiled_schema->contains_schema, ref_data);
|
|
50
|
+
resolve_refs(compiled_schema->propertyNames_schema, ref_data);
|
|
51
|
+
resolve_refs(compiled_schema->additionalProperties_schema, ref_data);
|
|
52
|
+
|
|
53
|
+
if(compiled_schema->allOf_val != Qundef)
|
|
54
|
+
resolve_refs_in_array(compiled_schema->allOf_val, ref_data);
|
|
55
|
+
|
|
56
|
+
if(compiled_schema->anyOf_val != Qundef)
|
|
57
|
+
resolve_refs_in_array(compiled_schema->anyOf_val, ref_data);
|
|
58
|
+
|
|
59
|
+
if(compiled_schema->oneOf_val != Qundef)
|
|
60
|
+
resolve_refs_in_array(compiled_schema->oneOf_val, ref_data);
|
|
61
|
+
|
|
62
|
+
if(RB_TYPE_P(compiled_schema->items_val, T_ARRAY))
|
|
63
|
+
resolve_refs_in_array(compiled_schema->items_val, ref_data);
|
|
64
|
+
|
|
65
|
+
if(compiled_schema->properties_val != Qundef)
|
|
66
|
+
rb_hash_foreach(compiled_schema->properties_val, resolve_refs_in_hash, ref_data);
|
|
67
|
+
|
|
68
|
+
if(compiled_schema->patternProperties_val != Qundef)
|
|
69
|
+
rb_hash_foreach(compiled_schema->patternProperties_val, resolve_refs_in_hash, ref_data);
|
|
70
|
+
|
|
71
|
+
if(compiled_schema->dependencies_val != Qundef)
|
|
72
|
+
rb_hash_foreach(compiled_schema->dependencies_val, resolve_refs_in_hash, ref_data);
|
|
73
|
+
|
|
74
|
+
if(compiled_schema->nested_schemas != NULL)
|
|
75
|
+
resolve_refs_for_nested_schemas(compiled_schema->nested_schemas, compiled_schema->nested_schemas_count, ref_data);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
void register_schema_for_ref_resolution(CompiledSchema *compiled_schema, VALUE ref_data) {
|
|
79
|
+
// Embed compiled schema into Ruby Hash
|
|
80
|
+
rb_hash_aset(ref_data, compiled_schema->path, PTR2NUM(compiled_schema));
|
|
81
|
+
|
|
82
|
+
// Embed compiled schema into Ruby Hash again if it has an $id
|
|
83
|
+
if(compiled_schema->id_val != Qundef)
|
|
84
|
+
rb_hash_aset(ref_data, compiled_schema->id_val, PTR2NUM(compiled_schema));
|
|
85
|
+
}
|