json-schema-validator/app
Sven Fink 6f3005dc75 Use json patch format for default
json patch (RFC 6902) makes it clearer in case of array contents. It is
supported by nlohmann::json and can be applied with `patch` to fill up
the json with defaults.
2020-03-03 11:04:23 +01:00
..
json-schema-validate.cpp Adapt CMake project name to be coherent with nlohmann::json's naming 2019-12-05 11:12:23 +01:00
readme.cpp Use json patch format for default 2020-03-03 11:04:23 +01:00

#include <iomanip>
#include <iostream>

#include <nlohmann/json-schema.hpp>

using nlohmann::json;
using nlohmann::json_schema::json_validator;

// The schema is defined based upon a string literal
static json person_schema = R"(
{
    "$schema": "http://json-schema.org/draft-07/schema#",
		"title": "Dict",
		"type": "array",
		"items": {
			"title": "A person",
			"properties": {
					"name": {
							"description": "Name",
							"type": "string"
					},
					"age": {
							"description": "Age of the person",
							"type": "number",
							"minimum": 2,
							"maximum": 200
					},
					"address":{
						"type": "object",
						"properties":{
							"street":{
								"type": "string",
								"default": "Abbey Road"
							}
						}
					}
				},
				"required": [
									"name",
									"age"
									],
				"type": "object"
			}
		}
)"_json;

// The people are defined with brace initialization
static json bad_person = R"([
	{"age": 42}
	])"_json;

static json good_person = R"([
	{
		"name": "Albert",
		"age": 42,
		"address": {"street": "Main Street"}
	}
])"_json;

static json good_defaulted_person = R"([
	{
		"name": "Albert",
		"age": 42,
		"address": {"street": "Main Street"}
	},
	{
		"name": "Knut",
		"age": 69,
		"address": {}
	}
])"_json;

int main()
{
	/* json-parse the schema */

	json_validator validator; // create validator

	try {
		validator.set_root_schema(person_schema); // insert root-schema
	} catch (const std::exception &e) {
		std::cerr << "Validation of schema failed, here is why: " << e.what() << "\n";
		return EXIT_FAILURE;
	}

	/* json-parse the people - API of 1.0.0, default throwing error handler */

	for (auto &person : {bad_person, good_person, good_defaulted_person}) {
		std::cout << "About to validate this person:\n"
		          << std::setw(2) << person << std::endl;
		try {
			auto defaultPatch = validator.validate(person); // validate the document - uses the default throwing error-handler
			std::cout << "Validation succeeded\n";
			std::cout << "Patch with defaults: " << defaultPatch.dump(2) << std::endl;
		} catch (const std::exception &e) {
			std::cerr << "Validation failed, here is why: " << e.what() << "\n";
		}
	}

	/* json-parse the people - with custom error handler */
	class custom_error_handler : public nlohmann::json_schema::basic_error_handler
	{
		void error(const nlohmann::json::json_pointer &ptr, const json &instance, const std::string &message) override
		{
			nlohmann::json_schema::basic_error_handler::error(ptr, instance, message);
			std::cerr << "ERROR: '" << ptr << "' - '" << instance << "': " << message << "\n";
		}
	};

	for (auto &person : {bad_person, good_person}) {
		std::cout << "About to validate this person:\n"
		          << std::setw(2) << person << std::endl;

		custom_error_handler err;
		validator.validate(person, err); // validate the document

		if (err)
			std::cerr << "Validation failed\n";
		else
			std::cout << "Validation succeeded\n";
	}

	return EXIT_SUCCESS;
}