MQTTSuite
Loading...
Searching...
No Matches
json-schema.hpp
Go to the documentation of this file.
1/*
2 * JSON schema validator for JSON for modern C++
3 *
4 * Copyright (c) 2016-2019 Patrick Boettcher <p@yai.se>.
5 *
6 * SPDX-License-Identifier: MIT
7 *
8 */
9#ifndef NLOHMANN_JSON_SCHEMA_HPP__
10#define NLOHMANN_JSON_SCHEMA_HPP__
11
12#ifdef _WIN32
13# if defined(JSON_SCHEMA_VALIDATOR_EXPORTS)
14# define JSON_SCHEMA_VALIDATOR_API __declspec(dllexport)
15# elif defined(JSON_SCHEMA_VALIDATOR_IMPORTS)
16# define JSON_SCHEMA_VALIDATOR_API __declspec(dllimport)
17# else
18# define JSON_SCHEMA_VALIDATOR_API
19# endif
20#else
21# define JSON_SCHEMA_VALIDATOR_API
22#endif
23
24#include <nlohmann/json.hpp>
25
26#ifdef NLOHMANN_JSON_VERSION_MAJOR
27# if (NLOHMANN_JSON_VERSION_MAJOR * 10000 + NLOHMANN_JSON_VERSION_MINOR * 100 + NLOHMANN_JSON_VERSION_PATCH) < 30800
28# error "Please use this library with NLohmann's JSON version 3.8.0 or higher"
29# endif
30#else
31# error "expected existing NLOHMANN_JSON_VERSION_MAJOR preproc variable, please update to NLohmann's JSON 3.8.0"
32#endif
33
34// make yourself a home - welcome to nlohmann's namespace
35namespace nlohmann
36{
37
38// A class representing a JSON-URI for schemas derived from
39// section 8 of JSON Schema: A Media Type for Describing JSON Documents
40// draft-wright-json-schema-00
41//
42// New URIs can be derived from it using the derive()-method.
43// This is useful for resolving refs or subschema-IDs in json-schemas.
44//
45// This is done implement the requirements described in section 8.2.
46//
48{
49 std::string urn_;
50
51 std::string scheme_;
52 std::string authority_;
53 std::string path_;
54
55 json::json_pointer pointer_; // fragment part if JSON-Pointer
56 std::string identifier_; // fragment part if Locatation Independent ID
57
58protected:
59 // decodes a JSON uri and replaces all or part of the currently stored values
60 void update(const std::string &uri);
61
62 std::tuple<std::string, std::string, std::string, std::string, std::string> as_tuple() const
63 {
64 return std::make_tuple(urn_, scheme_, authority_, path_, identifier_ != "" ? identifier_ : pointer_.to_string());
65 }
66
67public:
68 json_uri(const std::string &uri)
69 {
70 update(uri);
71 }
72
73 const std::string &scheme() const { return scheme_; }
74 const std::string &authority() const { return authority_; }
75 const std::string &path() const { return path_; }
76
77 const json::json_pointer &pointer() const { return pointer_; }
78 const std::string &identifier() const { return identifier_; }
79
80 std::string fragment() const
81 {
82 if (identifier_ == "")
83 return pointer_.to_string();
84 else
85 return identifier_;
86 }
87
88 std::string url() const { return location(); }
89 std::string location() const;
90
91 static std::string escape(const std::string &);
92
93 // create a new json_uri based in this one and the given uri
94 // resolves relative changes (pathes or pointers) and resets part if proto or hostname changes
95 json_uri derive(const std::string &uri) const
96 {
97 json_uri u = *this;
98 u.update(uri);
99 return u;
100 }
101
102 // append a pointer-field to the pointer-part of this uri
103 json_uri append(const std::string &field) const
104 {
105 if (identifier_ != "")
106 return *this;
107
108 json_uri u = *this;
109 u.pointer_ /= field;
110 return u;
111 }
112
113 std::string to_string() const;
114
115 friend bool operator<(const json_uri &l, const json_uri &r)
116 {
117 return l.as_tuple() < r.as_tuple();
118 }
119
120 friend bool operator==(const json_uri &l, const json_uri &r)
121 {
122 return l.as_tuple() == r.as_tuple();
123 }
124
125 friend std::ostream &operator<<(std::ostream &os, const json_uri &u);
126};
127
128namespace json_schema
129{
130
131extern json draft7_schema_builtin;
132
133typedef std::function<void(const json_uri & /*id*/, json & /*value*/)> schema_loader;
134typedef std::function<void(const std::string & /*format*/, const std::string & /*value*/)> format_checker;
135typedef std::function<void(const std::string & /*contentEncoding*/, const std::string & /*contentMediaType*/, const json & /*instance*/)> content_checker;
136
137// Interface for validation error handlers
139{
140public:
141 virtual ~error_handler() {}
142 virtual void error(const json::json_pointer & /*ptr*/, const json & /*instance*/, const std::string & /*message*/) = 0;
143};
144
146{
147 bool error_{false};
148
149public:
150 void error(const json::json_pointer & /*ptr*/, const json & /*instance*/, const std::string & /*message*/) override
151 {
152 error_ = true;
153 }
154
155 virtual void reset() { error_ = false; }
156 operator bool() const { return error_; }
157};
158
159/**
160 * Checks validity of JSON schema built-in string format specifiers like 'date-time', 'ipv4', ...
161 */
162void JSON_SCHEMA_VALIDATOR_API default_string_format_check(const std::string &format, const std::string &value);
163
164class root_schema;
165
167{
168 std::unique_ptr<root_schema> root_;
169
170public:
171 json_validator(schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr);
172
173 json_validator(const json &, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr);
174 json_validator(json &&, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr);
175
178
181
183
184 // insert and set the root-schema
185 void set_root_schema(const json &);
186 void set_root_schema(json &&);
187
188 // validate a json-document based on the root-schema
189 json validate(const json &) const;
190
191 // validate a json-document based on the root-schema with a custom error-handler
192 json validate(const json &, error_handler &, const json_uri &initial_uri = json_uri("#")) const;
193};
194
195} // namespace json_schema
196} // namespace nlohmann
197
198#endif /* NLOHMANN_JSON_SCHEMA_HPP__ */
void error(const json::json_pointer &, const json &, const std::string &) override
virtual void error(const json::json_pointer &, const json &, const std::string &)=0
json_validator & operator=(json_validator const &)=delete
std::unique_ptr< root_schema > root_
json_validator & operator=(json_validator &&)
json_validator(json &&, schema_loader=nullptr, format_checker=nullptr, content_checker=nullptr)
json_validator(schema_loader=nullptr, format_checker=nullptr, content_checker=nullptr)
json_validator(const json &, schema_loader=nullptr, format_checker=nullptr, content_checker=nullptr)
json_validator(json_validator const &)=delete
json validate(const json &, error_handler &, const json_uri &initial_uri=json_uri("#")) const
std::string authority_
const std::string & identifier() const
std::string fragment() const
std::string to_string() const
Definition json-uri.cpp:118
std::string url() const
friend bool operator==(const json_uri &l, const json_uri &r)
const std::string & authority() const
std::string scheme_
std::string location() const
Definition json-uri.cpp:102
void update(const std::string &uri)
Definition json-uri.cpp:16
json_uri(const std::string &uri)
static std::string escape(const std::string &)
Definition json-uri.cpp:137
friend bool operator<(const json_uri &l, const json_uri &r)
const std::string & scheme() const
const std::string & path() const
const json::json_pointer & pointer() const
json_uri derive(const std::string &uri) const
std::string identifier_
json::json_pointer pointer_
std::tuple< std::string, std::string, std::string, std::string, std::string > as_tuple() const
json_uri append(const std::string &field) const
static json uri_schema
Definition format.cpp:9
static json bad_uri
Definition format.cpp:23
static json good_uri
Definition format.cpp:22
static void uri_format_checker(const std::string &format, const std::string &value)
Definition format.cpp:25
int main()
Definition format.cpp:34
#define JSON_SCHEMA_VALIDATOR_API
std::function< void(const json_uri &, json &)> schema_loader
std::function< void(const std::string &, const std::string &)> format_checker
void default_string_format_check(const std::string &format, const std::string &value)
std::function< void(const std::string &, const std::string &, const json &)> content_checker