WIP facilitates inclusion of multiple meta-schema dialects

This commit is contained in:
Glen Mabey 2025-01-30 17:03:32 -07:00
parent a244024759
commit cd862228d6
11 changed files with 72 additions and 140 deletions

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "json-schema-spec"]
path = json-schema-spec/2020-12
url = ../../json-schema-org/json-schema-spec.git
[submodule "json-schema-spec_2019-09"]
path = json-schema-spec/2019-09
url = ../../json-schema-org/json-schema-spec.git

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.19)
# CMake version compatibility
# TODO: Remove when bumping cmake >= 3.25
if (POLICY CMP0140)
@ -151,6 +151,9 @@ add_subdirectory(src)
# Enable examples
# Convert meta-schema into strings and include into build
add_subdirectory(json-schema-spec)
# Enable testings
if (JSON_VALIDATOR_BUILD_TESTS)
enable_testing()
@ -161,7 +164,6 @@ if (JSON_VALIDATOR_BUILD_EXAMPLES)
add_subdirectory(example)
endif ()
#[==============================================================================================[
# Install or Export #
]==============================================================================================]

@ -0,0 +1 @@
Subproject commit c8eb3d320f60eca7cfb18da25337a426ceb40eaa

@ -0,0 +1 @@
Subproject commit 0d2e45422eda1dd5d3eb76905cb816b612d63a5b

View File

@ -0,0 +1,44 @@
#[==============================================================================================[
# Meta-schema Generation #
]==============================================================================================]
function (addSchemaFileToBuild META_SCHEMA_PATH)
file(READ ${META_SCHEMA_PATH} FILE_CONTENT)
string(JSON META_SCHEMA_ID GET ${FILE_CONTENT} "$id")
string(REPLACE "(" "-^-(" FILE_CONTENT "${FILE_CONTENT}") # work around the reality that there may be '(' within strings
string(REPLACE ")" ")-^-" FILE_CONTENT "${FILE_CONTENT}") # work around the reality that there may be ')' within strings
#string(REPLACE "\n" ")\"\nR\"(" FILE_CONTENT "${FILE_CONTENT}") # break lines into separate strings so that they are not too long for VS
set(SOURCES ${SOURCES} PARENT_SCOPE)
file (APPEND ${SCHEMA_CPP_FILE_NAME} " {\"${META_SCHEMA_ID}\",\nR\"(")
file (APPEND ${SCHEMA_CPP_FILE_NAME} ${FILE_CONTENT})
file (APPEND ${SCHEMA_CPP_FILE_NAME} ")\"_json},\n")
endfunction()
# this logic is such that the schema header file will only be generated once; until a "clean"
set(SCHEMA_BASE_FILE_NAME builtin_schema_map)
set(SCHEMA_BASE_FILE_PATH ${CMAKE_CURRENT_BINARY_DIR}/${SCHEMA_BASE_FILE_NAME})
set(SCHEMA_HEADER_FILE_NAME ${SCHEMA_BASE_FILE_PATH}.h)
set(SCHEMA_CPP_FILE_NAME ${SCHEMA_BASE_FILE_PATH}.cpp)
if (EXISTS ${SCHEMA_HEADER_FILE_NAME})
message("Not re-generating meta schema source files")
else()
file (WRITE ${SCHEMA_HEADER_FILE_NAME} "#include <map>\n#include <string>\n#include <nlohmann/json.hpp>\nnamespace nlohmann {\n namespace json_schema {\n const extern std::map<std::string,json> builtin_schema_map;\n }\n}\n")
file (WRITE ${SCHEMA_CPP_FILE_NAME} "#include \"${SCHEMA_BASE_FILE_NAME}.h\"\nnamespace nlohmann {\n namespace json_schema {\n const std::map<std::string,json> builtin_schema_map = {\n")
file (GLOB META_SCHEMA_PATHS
2019-09/meta/*.json
2020-12/meta/*.json
)
LIST(APPEND META_SCHEMA_PATHS
2019-09/schema.json
2020-12/schema.json
)
message("META_SCHEMA_PATHS = ${META_SCHEMA_PATHS}")
foreach(ext_json_path ${META_SCHEMA_PATHS})
addSchemaFileToBuild(${ext_json_path} APPEND) # subsequent invocations of addSchemaFileToBuild(), use APPEND
endforeach()
file (APPEND ${SCHEMA_CPP_FILE_NAME} " };\n }\n}\n")
endif()
target_sources(nlohmann_json_schema_validator PRIVATE ${SCHEMA_CPP_FILE_NAME})
target_include_directories(nlohmann_json_schema_validator PRIVATE ${CMAKE_BINARY_DIR}/json-schema-spec)

View File

@ -0,0 +1,11 @@
# JSON Schema Spec
This directory contains several dialects of the JSON, also known
as meta-schema.
This is done using git submodules, so that the upstream version
can be tracked and updated easily.
The `2019-09` dialect is not really supported, nor is it intended
to be.
However, it is included here as an example of how multiple dialects
will be supported, looking forward to the next release.

58
schema
View File

@ -1,58 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://json-schema.org/draft/2020-12/schema",
"$vocabulary": {
"https://json-schema.org/draft/2020-12/vocab/core": true,
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
"https://json-schema.org/draft/2020-12/vocab/validation": true,
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
"https://json-schema.org/draft/2020-12/vocab/content": true
},
"$dynamicAnchor": "meta",
"title": "Core and Validation specifications meta-schema",
"allOf": [
{"$ref": "meta/core"},
{"$ref": "meta/applicator"},
{"$ref": "meta/unevaluated"},
{"$ref": "meta/validation"},
{"$ref": "meta/meta-data"},
{"$ref": "meta/format-annotation"},
{"$ref": "meta/content"}
],
"type": ["object", "boolean"],
"$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.",
"properties": {
"definitions": {
"$comment": "\"definitions\" has been replaced by \"$defs\".",
"type": "object",
"additionalProperties": { "$dynamicRef": "#meta" },
"deprecated": true,
"default": {}
},
"dependencies": {
"$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.",
"type": "object",
"additionalProperties": {
"anyOf": [
{ "$dynamicRef": "#meta" },
{ "$ref": "meta/validation#/$defs/stringArray" }
]
},
"deprecated": true,
"default": {}
},
"$recursiveAnchor": {
"$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".",
"$ref": "meta/core#/$defs/anchorString",
"deprecated": true
},
"$recursiveRef": {
"$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".",
"$ref": "meta/core#/$defs/uriReferenceString",
"deprecated": true
}
}
}

View File

@ -1,6 +1,5 @@
target_sources(nlohmann_json_schema_validator PRIVATE
smtp-address-validator.cpp
json-schema-draft_2020-12.json.cpp
json-uri.cpp
json-validator.cpp
json-patch.cpp

View File

@ -1,75 +0,0 @@
/*
* JSON schema validator for JSON for modern C++
*
* Copyright (c) 2016-2019 Patrick Boettcher <p@yai.se>.
*
* SPDX-License-Identifier: MIT
*
*/
#include <nlohmann/json.hpp>
namespace nlohmann
{
namespace json_schema
{
json draft_2020_12_schema_builtin = R"( {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://json-schema.org/draft/2020-12/schema",
"$vocabulary": {
"https://json-schema.org/draft/2020-12/vocab/core": true,
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
"https://json-schema.org/draft/2020-12/vocab/validation": true,
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
"https://json-schema.org/draft/2020-12/vocab/content": true
},
"$dynamicAnchor": "meta",
"title": "Core and Validation specifications meta-schema",
"allOf": [
{"$ref": "meta/core"},
{"$ref": "meta/applicator"},
{"$ref": "meta/unevaluated"},
{"$ref": "meta/validation"},
{"$ref": "meta/meta-data"},
{"$ref": "meta/format-annotation"},
{"$ref": "meta/content"}
],
"type": ["object", "boolean"],
"$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.",
"properties": {
"definitions": {
"$comment": "\"definitions\" has been replaced by \"$defs\".",
"type": "object",
"additionalProperties": { "$dynamicRef": "#meta" },
"deprecated": true,
"default": {}
},
"dependencies": {
"$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.",
"type": "object",
"additionalProperties": {
"anyOf": [
{ "$dynamicRef": "#meta" },
{ "$ref": "meta/validation#/$defs/stringArray" }
]
},
"deprecated": true,
"default": {}
},
"$recursiveAnchor": {
"$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".",
"$ref": "meta/core#/$defs/anchorString",
"deprecated": true
},
"$recursiveRef": {
"$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".",
"$ref": "meta/core#/$defs/uriReferenceString",
"deprecated": true
}
}
} )"_json;
}
} // namespace nlohmann

View File

@ -31,6 +31,8 @@
# error "expected existing NLOHMANN_JSON_VERSION_MAJOR preproc variable, please update to NLohmann's JSON 3.8.0"
#endif
//#include "builtin_schema_map.h"
// make yourself a home - welcome to nlohmann's namespace
namespace nlohmann
{
@ -127,8 +129,7 @@ public:
namespace json_schema
{
extern json draft_2020_12_schema_builtin;
const extern std::map<std::string,json> builtin_schema_map;
typedef std::function<void(const json_uri & /*id*/, json & /*value*/)> schema_loader;
typedef std::function<void(const std::string & /*format*/, const std::string & /*value*/)> format_checker;

View File

@ -18,8 +18,8 @@ using nlohmann::json_schema::json_validator;
static void loader(const json_uri &uri, json &schema)
{
if (uri.location() == "http://json-schema.org/draft/2020-12/schema") {
schema = nlohmann::json_schema::draft_2020_12_schema_builtin;
if (nlohmann::json_schema::builtin_schema_map.count(uri.location()) > 0) {
schema = nlohmann::json_schema::builtin_schema_map.at(uri.location());
return;
}