@@ -150,6 +150,20 @@ auto type_expression_of(const sourcemeta::core::JSON &schema,
150150 type_expression_of (schema.at (" unevaluatedItems" ), frame,
151151 root, visited, ref_chain));
152152 }
153+ } else if (schema.defines (" items" ) && schema.at (" items" ).is_array ()) {
154+ result.assign (" kind" , sourcemeta::core::JSON{" tuple" });
155+ auto items{sourcemeta::core::JSON::make_array ()};
156+ for (const auto &item : schema.at (" items" ).as_array ()) {
157+ items.push_back (
158+ type_expression_of (item, frame, root, visited, ref_chain));
159+ }
160+ result.assign (" items" , std::move (items));
161+ if (schema.defines (" additionalItems" ) &&
162+ schema.at (" additionalItems" ).is_object ()) {
163+ result.assign (" additional" ,
164+ type_expression_of (schema.at (" additionalItems" ), frame,
165+ root, visited, ref_chain));
166+ }
153167 } else {
154168 result.assign (" kind" , sourcemeta::core::JSON{" array" });
155169 if (schema.defines (" items" ) && schema.at (" items" ).is_object ()) {
@@ -274,12 +288,18 @@ auto constraints_of(const sourcemeta::core::JSON &schema)
274288 }
275289
276290 if (schema.defines (" minimum" ) && schema.at (" minimum" ).is_number ()) {
291+ const auto exclusive{schema.defines (" exclusiveMinimum" ) &&
292+ schema.at (" exclusiveMinimum" ).is_boolean () &&
293+ schema.at (" exclusiveMinimum" ).to_boolean ()};
277294 constraints.push_back (sourcemeta::core::JSON{
278- " > = " + format_json_number (schema.at (" minimum" ))});
295+ (exclusive ? " > " : " > = " ) + format_json_number (schema.at (" minimum" ))});
279296 }
280297 if (schema.defines (" maximum" ) && schema.at (" maximum" ).is_number ()) {
298+ const auto exclusive{schema.defines (" exclusiveMaximum" ) &&
299+ schema.at (" exclusiveMaximum" ).is_boolean () &&
300+ schema.at (" exclusiveMaximum" ).to_boolean ()};
281301 constraints.push_back (sourcemeta::core::JSON{
282- " < = " + format_json_number (schema.at (" maximum" ))});
302+ (exclusive ? " < " : " < = " ) + format_json_number (schema.at (" maximum" ))});
283303 }
284304 if (schema.defines (" exclusiveMinimum" ) &&
285305 schema.at (" exclusiveMinimum" ).is_number ()) {
@@ -774,19 +794,27 @@ auto walk_prefix_items(const sourcemeta::core::JSON &schema,
774794 const sourcemeta::core::JSON &root,
775795 VisitedSchemas &visited, std::size_t &next_identifier)
776796 -> void {
777- if (!schema.is_object () || !schema.defines (" prefixItems" ) ||
778- !schema.at (" prefixItems" ).is_array ()) {
797+ const auto has_prefix_items{schema.is_object () &&
798+ schema.defines (" prefixItems" ) &&
799+ schema.at (" prefixItems" ).is_array ()};
800+ const auto has_draft4_tuple{!has_prefix_items && schema.is_object () &&
801+ schema.defines (" items" ) &&
802+ schema.at (" items" ).is_array ()};
803+ if (!has_prefix_items && !has_draft4_tuple) {
779804 return ;
780805 }
781806
807+ const auto &tuple_items{has_prefix_items ? schema.at (" prefixItems" )
808+ : schema.at (" items" )};
809+
782810 std::size_t min_items{0 };
783811 if (schema.defines (" minItems" ) && schema.at (" minItems" ).is_integer () &&
784812 schema.at (" minItems" ).to_integer () > 0 ) {
785813 min_items = static_cast <std::size_t >(schema.at (" minItems" ).to_integer ());
786814 }
787815
788816 std::size_t index{0 };
789- for (const auto &item : schema. at ( " prefixItems " ) .as_array ()) {
817+ for (const auto &item : tuple_items .as_array ()) {
790818 if (is_complex_schema (item)) {
791819 auto section_children{sourcemeta::core::JSON::make_array ()};
792820 section_children.push_back (
@@ -847,11 +875,18 @@ auto walk_prefix_items(const sourcemeta::core::JSON &schema,
847875 ++index;
848876 }
849877
850- if (schema.defines (" items" ) && schema.at (" items" ).is_object ()) {
878+ if (has_prefix_items && schema.defines (" items" ) &&
879+ schema.at (" items" ).is_object ()) {
851880 auto path{base_path};
852881 path.push_back (make_path_segment (" wildcard" , " *" ));
853882 emit_row (schema.at (" items" ), std::move (path), rows, frame, root, visited,
854883 next_identifier);
884+ } else if (has_draft4_tuple && schema.defines (" additionalItems" ) &&
885+ schema.at (" additionalItems" ).is_object ()) {
886+ auto path{base_path};
887+ path.push_back (make_path_segment (" wildcard" , " *" ));
888+ emit_row (schema.at (" additionalItems" ), std::move (path), rows, frame, root,
889+ visited, next_identifier);
855890 }
856891}
857892
0 commit comments