Skip to content

Commit b77c386

Browse files
Adds support for list of unions in json schema
1 parent 7663dab commit b77c386

File tree

4 files changed

+181
-1
lines changed

4 files changed

+181
-1
lines changed

scripts/generate_code.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ def glob(path, pattern):
333333
schema="arrays_test.fbs",
334334
)
335335

336+
flatc(
337+
["--jsonschema", "--schema"],
338+
prefix="union_vector",
339+
schema="union_vector/union_vector.fbs",
340+
)
341+
336342
flatc(
337343
RUST_OPTS,
338344
prefix="arrays_test",

src/idl_gen_json_schema.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,42 @@ static std::string GenArrayType(const Type &type) {
102102
element_type = GenTypeRef(type.struct_def);
103103
} else if (type.enum_def != nullptr) {
104104
element_type = GenTypeRef(type.enum_def);
105+
} else if (type.element == BASE_TYPE_UNION) {
106+
// Vector of union values
107+
std::string union_type_string("\"anyOf\": [");
108+
const auto &union_types = type.enum_def->Vals();
109+
bool first = true;
110+
for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) {
111+
const auto &union_type = *ut;
112+
if (union_type->union_type.base_type == BASE_TYPE_NONE) { continue; }
113+
114+
if (!first) union_type_string.append(",");
115+
first = false;
116+
117+
if (union_type->union_type.base_type == BASE_TYPE_STRUCT) {
118+
union_type_string.append(
119+
"{ " + GenTypeRef(union_type->union_type.struct_def) + " }");
120+
} else if (union_type->union_type.base_type == BASE_TYPE_STRING) {
121+
union_type_string.append("{ \"type\": \"string\" }");
122+
}
123+
}
124+
union_type_string.append("]");
125+
element_type = union_type_string;
126+
} else if (type.element == BASE_TYPE_UTYPE) {
127+
// Vector of union type indicators (the _type field for a vector of unions)
128+
std::string enumdef = "\"type\" : \"string\", \"enum\": [";
129+
const auto &union_types = type.enum_def->Vals();
130+
bool first = true;
131+
for (auto enum_value = union_types.begin(); enum_value != union_types.end();
132+
++enum_value) {
133+
if ((*enum_value)->union_type.base_type == BASE_TYPE_NONE) { continue; }
134+
135+
if (!first) enumdef.append(", ");
136+
first = false;
137+
enumdef.append("\"" + (*enum_value)->name + "\"");
138+
}
139+
enumdef.append("]");
140+
element_type = enumdef;
105141
} else {
106142
element_type = GenType(type.element);
107143
}

src/idl_parser.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2703,7 +2703,8 @@ bool Parser::SupportsAdvancedUnionFeatures() const {
27032703
~(IDLOptions::kCpp | IDLOptions::kTs | IDLOptions::kPhp |
27042704
IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kKotlin |
27052705
IDLOptions::kBinary | IDLOptions::kSwift | IDLOptions::kNim |
2706-
IDLOptions::kJson | IDLOptions::kKotlinKmp)) == 0;
2706+
IDLOptions::kJson | IDLOptions::kJsonSchema |
2707+
IDLOptions::kKotlinKmp)) == 0;
27072708
}
27082709

27092710
bool Parser::SupportsAdvancedArrayFeatures() const {
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2019-09/schema",
3+
"definitions": {
4+
"Character" : {
5+
"anyOf": [{ "$ref" : "#/definitions/Attacker" },{ "$ref" : "#/definitions/Rapunzel" },{ "$ref" : "#/definitions/BookReader" },{ "$ref" : "#/definitions/BookReader" },,]
6+
},
7+
"Gadget" : {
8+
"anyOf": [{ "$ref" : "#/definitions/FallingTub" },{ "$ref" : "#/definitions/HandFan" }]
9+
},
10+
"Attacker" : {
11+
"type" : "object",
12+
"properties" : {
13+
"sword_attack_damage" : {
14+
"type" : "integer", "minimum" : -2147483648, "maximum" : 2147483647
15+
}
16+
},
17+
"additionalProperties" : false
18+
},
19+
"Rapunzel" : {
20+
"type" : "object",
21+
"properties" : {
22+
"hair_length" : {
23+
"type" : "integer", "minimum" : -2147483648, "maximum" : 2147483647
24+
}
25+
},
26+
"additionalProperties" : false
27+
},
28+
"BookReader" : {
29+
"type" : "object",
30+
"properties" : {
31+
"books_read" : {
32+
"type" : "integer", "minimum" : -2147483648, "maximum" : 2147483647
33+
}
34+
},
35+
"additionalProperties" : false
36+
},
37+
"FallingTub" : {
38+
"type" : "object",
39+
"properties" : {
40+
"weight" : {
41+
"type" : "integer", "minimum" : -2147483648, "maximum" : 2147483647
42+
}
43+
},
44+
"additionalProperties" : false
45+
},
46+
"HandFan" : {
47+
"type" : "object",
48+
"properties" : {
49+
"length" : {
50+
"type" : "integer", "minimum" : -2147483648, "maximum" : 2147483647
51+
}
52+
},
53+
"additionalProperties" : false
54+
},
55+
"Movie" : {
56+
"type" : "object",
57+
"properties" : {
58+
"main_character_type" : {
59+
"type" : "string", "enum": ["NONE", "MuLan", "Rapunzel", "Belle", "BookFan", "Other", "Unused"]
60+
},
61+
"main_character" : {
62+
"oneOf": [{ "type": "object", "properties": { "type": { "const": "MuLan" }, "value": { "$ref" : "#/definitions/Attacker" } }, "required": ["type", "value"] },{ "type": "object", "properties": { "type": { "const": "Rapunzel" }, "value": { "$ref" : "#/definitions/Rapunzel" } }, "required": ["type", "value"] },{ "type": "object", "properties": { "type": { "const": "Belle" }, "value": { "$ref" : "#/definitions/BookReader" } }, "required": ["type", "value"] },{ "type": "object", "properties": { "type": { "const": "BookFan" }, "value": { "$ref" : "#/definitions/BookReader" } }, "required": ["type", "value"] }]
63+
},
64+
"characters_type" : {
65+
"type" : "array", "items" : {"$ref" : "#/definitions/Character"}
66+
},
67+
"characters" : {
68+
"type" : "array", "items" : {"$ref" : "#/definitions/Character"}
69+
}
70+
},
71+
"allOf": [
72+
{
73+
"if": {
74+
"properties": {
75+
"main_character_type": { "const": "NONE" }
76+
}
77+
},
78+
"then": {
79+
"not": {
80+
"required": ["main_character"]
81+
}
82+
}
83+
},
84+
{
85+
"if": {
86+
"properties": {
87+
"main_character_type": { "const": "MuLan" }
88+
}
89+
},
90+
"then": {
91+
"properties": {
92+
"main_character": { "$ref" : "#/definitions/Attacker" }
93+
}
94+
}
95+
},
96+
{
97+
"if": {
98+
"properties": {
99+
"main_character_type": { "const": "Rapunzel" }
100+
}
101+
},
102+
"then": {
103+
"properties": {
104+
"main_character": { "$ref" : "#/definitions/Rapunzel" }
105+
}
106+
}
107+
},
108+
{
109+
"if": {
110+
"properties": {
111+
"main_character_type": { "const": "Belle" }
112+
}
113+
},
114+
"then": {
115+
"properties": {
116+
"main_character": { "$ref" : "#/definitions/BookReader" }
117+
}
118+
}
119+
},
120+
{
121+
"if": {
122+
"properties": {
123+
"main_character_type": { "const": "BookFan" }
124+
}
125+
},
126+
"then": {
127+
"properties": {
128+
"main_character": { "$ref" : "#/definitions/BookReader" }
129+
}
130+
}
131+
}
132+
],
133+
"additionalProperties" : false
134+
}
135+
},
136+
"$ref" : "#/definitions/Movie"
137+
}

0 commit comments

Comments
 (0)