json: fix top-level $refs

This commit is contained in:
ochafik 2024-03-15 00:52:36 +00:00
parent 5a7deb27d5
commit 3b3ad949f5
4 changed files with 68 additions and 4 deletions

View file

@ -303,7 +303,7 @@ class SchemaConverter:
rule_name = name or 'root'
if (ref := schema.get('$ref')) is not None:
return self._resolve_ref(ref)
return self._add_rule(rule_name, self._resolve_ref(ref))
elif 'oneOf' in schema or 'anyOf' in schema:
return self._add_rule(rule_name, self._generate_union_rule(name, schema.get('oneOf') or schema['anyOf']))

View file

@ -526,7 +526,7 @@ public:
string rule_name = name.empty() ? "root" : name;
if (schema.contains("$ref")) {
return _resolve_ref(schema["$ref"]);
return _add_rule(rule_name, _resolve_ref(schema["$ref"]));
} else if (schema.contains("oneOf") || schema.contains("anyOf")) {
vector<json> alt_schemas = schema.contains("oneOf") ? schema["oneOf"].get<vector<json>>() : schema["anyOf"].get<vector<json>>();
return _add_rule(rule_name, _generate_union_rule(name, alt_schemas));

View file

@ -330,7 +330,7 @@ export class SchemaConverter {
const ref = schema.$ref;
if (ref !== undefined) {
return this._resolveRef(ref);
return this._addRule(ruleName, this._resolveRef(ref));
} else if (schema.oneOf || schema.anyOf) {
return this._addRule(ruleName, this._generateUnionRule(name, schema.oneOf || schema.anyOf));
} else if (Array.isArray(schemaType)) {

View file

@ -84,7 +84,7 @@ int main() {
run_all({
.name = "exotic formats",
.schema = R"""({
"prefixItems": [
"items": [
{ "format": "date" },
{ "format": "uuid" },
{ "format": "time" },
@ -140,6 +140,37 @@ int main() {
)"""
});
run_all({
.name = "tuple1",
.schema = R"""({
"prefixItems": [{ "type": "string" }]
})""",
.expected = R"""(
root ::= "[" space string "]" space
space ::= " "?
string ::= "\"" (
[^"\\] |
"\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
)* "\"" space
)"""
});
run_all({
.name = "tuple2",
.schema = R"""({
"prefixItems": [{ "type": "string" }, { "type": "number" }]
})""",
.expected = R"""(
number ::= ("-"? ([0-9] | [1-9] [0-9]*)) ("." [0-9]+)? ([eE] [-+]? [0-9]+)? space
root ::= "[" space string "," space number "]" space
space ::= " "?
string ::= "\"" (
[^"\\] |
"\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
)* "\"" space
)"""
});
run_all({
.name = "number",
.schema = R"""({
@ -298,4 +329,37 @@ int main() {
)* "\"" space
)"""
});
run_all({
.name = "top-level $ref",
.schema = R"""({
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/MyType",
"definitions": {
"MyType": {
"type": "object",
"properties": {
"a": {
"type": "string"
}
},
"required": [
"a"
],
"additionalProperties": false
}
}
})""",
.expected = R"""(
MyType ::= "{" space MyType-a-kv "}" space
MyType-a-kv ::= "\"a\"" space ":" space string
root ::= MyType
space ::= " "?
string ::= "\"" (
[^"\\] |
"\\" (["\\/bfnrt] | "u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F])
)* "\"" space
)"""
});
}