validator: update API so that the root-schema-insertion can be located in a try-catch-block
This commit is contained in:
parent
8939ba9b05
commit
5e9605b055
76
README.md
76
README.md
@ -2,23 +2,38 @@
|
||||
|
||||
# What is it?
|
||||
|
||||
This is a C++ header-only library for validating JSON documents based on a
|
||||
This is a C++ library for validating JSON documents based on a
|
||||
[JSON Schema](http://json-schema.org/) which itself should validate with
|
||||
[draft-4 of JSON Schema Validation](http://json-schema.org/schema).
|
||||
|
||||
First a disclaimer: *Everything here should be considered work in progress and
|
||||
First a disclaimer: *It is work in progress and
|
||||
contributions or hints or discussions are welcome.*
|
||||
|
||||
Niels Lohmann et al develop a great JSON parser for C++ called [JSON for Modern
|
||||
C++](https://github.com/nlohmann/json). This validator is based on this
|
||||
library, hence the name.
|
||||
|
||||
The name is for the moment purely marketing, because there is, IMHO, not much
|
||||
modern C++ inside. But I think the whole thing could be rewritten mode "modern".
|
||||
The name is for the moment purely marketing, because there is, IMHO, not so much
|
||||
modern C++ inside. There is plenty of space to make it more modern.
|
||||
|
||||
External documentation is missing as well. However the API of the validator
|
||||
will be rather simple.
|
||||
|
||||
# Design goals
|
||||
|
||||
The main goal of this validator is to produce *human-comprehensible* error
|
||||
messages if a JSON-document/instance does not comply with its schema. This is
|
||||
done with exceptions thrown at the users with a helpful message telling what's
|
||||
wrong with the document while validating.
|
||||
|
||||
Another goal was to use Niels Lohmann's JSON-library. This is why the validator
|
||||
lives in his namespace.
|
||||
|
||||
# Weaknesses
|
||||
|
||||
Schema-reference resolution is not recursivity-proven: If there is a nested
|
||||
cross-schema reference, it will not stop. (Though I haven't tested it)
|
||||
|
||||
# How to use
|
||||
|
||||
## Build
|
||||
@ -44,9 +59,11 @@ add_library(json-hpp INTERFACE)
|
||||
target_include_directories(json-hpp
|
||||
INTERFACE
|
||||
path/to/json.hpp)
|
||||
set(JSON_SCHEMA_TEST_SUITE_PATH "path/to/json-schema-test-suite")
|
||||
|
||||
# set this path to schema-test-suite to get tests compiled - optional
|
||||
set(JSON_SCHEMA_TEST_SUITE_PATH "path/to/json-schema-test-suite")
|
||||
enable_testing() # if you want to inherit tests
|
||||
|
||||
add_subdirectory(path-to-this-project json-schema-validator)
|
||||
```
|
||||
|
||||
@ -58,20 +75,37 @@ See also `app/json-schema-validate.cpp`.
|
||||
#include "json-schema-validator.hpp"
|
||||
|
||||
using nlohmann::json;
|
||||
using nlohmann::json_validator;
|
||||
using nlohmann::json_uri;
|
||||
using nlohmann::json_schema_draft4::json_validator;
|
||||
|
||||
static void loader(const json_uri &uri, json &schema)
|
||||
{
|
||||
// get the schema from uri and feed it into schema
|
||||
// if not possible, otherwise, throw an excpetion
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
json schema, document;
|
||||
json schema;
|
||||
|
||||
/* fill in the schema */
|
||||
/* fill in the document */
|
||||
/* json-parse the schema */
|
||||
|
||||
json_validator validator;
|
||||
json_validator validator(loader); // create validator with a loader-callback
|
||||
|
||||
try {
|
||||
validator.validate(document, scheam);
|
||||
} catch (const std::out_of_range &e) {
|
||||
validator.set_root_schema(schema); // insert root-schema
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Validation failed, here is why: " << e.what() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
json document;
|
||||
|
||||
/* json-parse the document */
|
||||
|
||||
try {
|
||||
validator.validate(document); // validate the document
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Validation failed, here is why: " << e.what() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -84,15 +118,19 @@ int main(void)
|
||||
There is an application which can be used for testing the validator with the
|
||||
[JSON-Schema-Test-Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
|
||||
|
||||
Currently **72** of ~**308** tests are still failing, because simply not all keywords and
|
||||
their functionalities have been implemented. Some of the missing feature will
|
||||
require a rework. Some will only work with external libraries. (remote references)
|
||||
If you have cloned this repository providing a path the repository-root via the
|
||||
cmake-variable `JSON_SCHEMA_TEST_SUITE_PATH` will enable the test-target(s).
|
||||
|
||||
Currently **31** of **304** tests are failing:
|
||||
|
||||
- 22 of them are `format`-strings which are not supported.
|
||||
- 3 of them are because `pattern` is not implemented for strings
|
||||
- and 6 bugs
|
||||
|
||||
# Additional features
|
||||
|
||||
## Default value population
|
||||
## Default values
|
||||
|
||||
For my use case I need something to populate default values into the JSON
|
||||
instance of properties which are not set by the user.
|
||||
The goal is to create an empty document, based on schema-defined
|
||||
default-values, recursively populated.
|
||||
|
||||
This feature can be enable by setting the `default_value_insertion` to true.
|
||||
|
||||
@ -80,7 +80,9 @@ int main(void)
|
||||
|
||||
const auto &schema = test_group["schema"];
|
||||
|
||||
json_validator validator(schema, loader);
|
||||
json_validator validator(loader);
|
||||
|
||||
validator.set_root_schema(schema);
|
||||
|
||||
for (auto &test_case : test_group["tests"]) {
|
||||
std::cout << " Testing Case " << test_case["description"] << "\n";
|
||||
|
||||
@ -80,9 +80,17 @@ int main(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// 2) insert this schema to the validator
|
||||
// this resolves remote-schemas, sub-schemas and references via the given loader-function
|
||||
json_validator validator(schema, loader);
|
||||
// 2) create the validator and
|
||||
json_validator validator(loader);
|
||||
|
||||
try {
|
||||
// insert this schema as the root to the validator
|
||||
// this resolves remote-schemas, sub-schemas and references via the given loader-function
|
||||
validator.set_root_schema(schema);
|
||||
} catch (std::exception &e) {
|
||||
std::cerr << "setting root schema failed\n";
|
||||
std::cerr << e.what() << "\n";
|
||||
}
|
||||
|
||||
// 3) do the actual validation of the document
|
||||
json document;
|
||||
|
||||
@ -170,24 +170,16 @@ class json_validator
|
||||
void insert_schema(const json &input, const json_uri &id);
|
||||
|
||||
public:
|
||||
json_validator(const json &schema, std::function<void(const json_uri &, json &)> loader);
|
||||
json_validator(std::function<void(const json_uri &, json &)> loader = nullptr)
|
||||
: schema_loader_(loader)
|
||||
{
|
||||
}
|
||||
|
||||
// insert and set a root-schema
|
||||
void set_root_schema(const json &);
|
||||
|
||||
// validate a json-document based on the root-schema
|
||||
void validate(json &instance);
|
||||
|
||||
// insert default values items into object
|
||||
// if the key is not present before checking their
|
||||
// validity in regards to their schema
|
||||
//
|
||||
// breaks JSON-Schema-Test-Suite if true
|
||||
// *PARTIALLY IMPLEMENTED* only for properties of objects
|
||||
bool default_value_insertion = false;
|
||||
|
||||
// recursively insert default values and create parent objects if
|
||||
// they would be empty
|
||||
//
|
||||
// breaks JSON-Schema-Test-Suite if true
|
||||
// *NOT YET IMPLEMENTED* -> maybe the same as the above option, need more thoughts
|
||||
bool recursive_default_value_insertion = false;
|
||||
};
|
||||
|
||||
} // json_schema_draft4
|
||||
|
||||
@ -326,8 +326,7 @@ void json_validator::validate(json &instance)
|
||||
validate(instance, *root_schema_, "root");
|
||||
}
|
||||
|
||||
json_validator::json_validator(const json &schema, std::function<void(const json_uri &, json &)> loader)
|
||||
: schema_loader_(loader)
|
||||
void json_validator::set_root_schema(const json &schema)
|
||||
{
|
||||
insert_schema(schema, json_uri("#"));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user