make default-values work for stacked $refs
This commit is contained in:
parent
afe3cc1555
commit
40f5d293fa
@ -65,7 +65,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// 2) create the validator and
|
// 2) create the validator and
|
||||||
json_validator validator(loader,
|
json_validator validator(loader,
|
||||||
nlohmann::json_schema::default_string_format_check);
|
nlohmann::json_schema::default_string_format_check);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// insert this schema as the root to the validator
|
// insert this schema as the root to the validator
|
||||||
|
|||||||
@ -34,12 +34,11 @@ using namespace nlohmann::json_schema;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
static const json EmptyDefault = nullptr;
|
|
||||||
|
|
||||||
class schema
|
class schema
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
root_schema *root_;
|
root_schema *root_;
|
||||||
|
json default_value_ = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~schema() = default;
|
virtual ~schema() = default;
|
||||||
@ -49,11 +48,13 @@ public:
|
|||||||
|
|
||||||
virtual void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const = 0;
|
virtual void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const = 0;
|
||||||
|
|
||||||
virtual const json &defaultValue(const json::json_pointer &, const json &, error_handler &) const
|
virtual const json &default_value(const json::json_pointer &, const json &, error_handler &) const
|
||||||
{
|
{
|
||||||
return EmptyDefault;
|
return default_value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_default_value(const json &v) { default_value_ = v; }
|
||||||
|
|
||||||
static std::shared_ptr<schema> make(json &schema,
|
static std::shared_ptr<schema> make(json &schema,
|
||||||
root_schema *root,
|
root_schema *root,
|
||||||
const std::vector<std::string> &key,
|
const std::vector<std::string> &key,
|
||||||
@ -75,16 +76,18 @@ class schema_ref : public schema
|
|||||||
e.error(ptr, instance, "unresolved or freed schema-reference " + id_);
|
e.error(ptr, instance, "unresolved or freed schema-reference " + id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const json &defaultValue(const json::json_pointer &ptr, const json &instance, error_handler &e) const override
|
const json &default_value(const json::json_pointer &ptr, const json &instance, error_handler &e) const override final
|
||||||
{
|
{
|
||||||
|
if (!default_value_.is_null())
|
||||||
|
return default_value_;
|
||||||
|
|
||||||
auto target = target_.lock();
|
auto target = target_.lock();
|
||||||
|
|
||||||
if (target)
|
if (target)
|
||||||
return target->defaultValue(ptr, instance, e);
|
return target->default_value(ptr, instance, e);
|
||||||
else
|
|
||||||
e.error(ptr, instance, "unresolved or freed schema-reference " + id_);
|
|
||||||
|
|
||||||
return EmptyDefault;
|
e.error(ptr, instance, "unresolved or freed schema-reference " + id_);
|
||||||
|
|
||||||
|
return default_value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -347,9 +350,9 @@ class logical_not : public schema
|
|||||||
e.error(ptr, instance, "the subschema has succeeded, but it is required to not validate");
|
e.error(ptr, instance, "the subschema has succeeded, but it is required to not validate");
|
||||||
}
|
}
|
||||||
|
|
||||||
const json &defaultValue(const json::json_pointer &ptr, const json &instance, error_handler &e) const override
|
const json &default_value(const json::json_pointer &ptr, const json &instance, error_handler &e) const override
|
||||||
{
|
{
|
||||||
return subschema_->defaultValue(ptr, instance, e);
|
return subschema_->default_value(ptr, instance, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -443,7 +446,6 @@ bool logical_combination<oneOf>::is_validate_complete(const json &instance, cons
|
|||||||
|
|
||||||
class type_schema : public schema
|
class type_schema : public schema
|
||||||
{
|
{
|
||||||
json defaultValue_ = EmptyDefault;
|
|
||||||
std::vector<std::shared_ptr<schema>> type_;
|
std::vector<std::shared_ptr<schema>> type_;
|
||||||
std::pair<bool, json> enum_, const_;
|
std::pair<bool, json> enum_, const_;
|
||||||
std::vector<std::shared_ptr<schema>> logic_;
|
std::vector<std::shared_ptr<schema>> logic_;
|
||||||
@ -456,11 +458,6 @@ class type_schema : public schema
|
|||||||
|
|
||||||
std::shared_ptr<schema> if_, then_, else_;
|
std::shared_ptr<schema> if_, then_, else_;
|
||||||
|
|
||||||
const json &defaultValue(const json::json_pointer &, const json &, error_handler &) const override
|
|
||||||
{
|
|
||||||
return defaultValue_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override final
|
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override final
|
||||||
{
|
{
|
||||||
// depending on the type of instance run the type specific validator - if present
|
// depending on the type of instance run the type specific validator - if present
|
||||||
@ -551,9 +548,10 @@ public:
|
|||||||
sch.erase(attr);
|
sch.erase(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto default_attr = sch.find("default");
|
attr = sch.find("default");
|
||||||
if (default_attr != sch.end()) {
|
if (attr != sch.end()) {
|
||||||
defaultValue_ = default_attr.value();
|
set_default_value(attr.value());
|
||||||
|
sch.erase(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &key : known_keywords)
|
for (auto &key : known_keywords)
|
||||||
@ -630,11 +628,6 @@ public:
|
|||||||
sch.erase(attr);
|
sch.erase(attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_default_value(const json &default_value)
|
|
||||||
{
|
|
||||||
defaultValue_ = default_value;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class string : public schema
|
class string : public schema
|
||||||
@ -986,9 +979,9 @@ class object : public schema
|
|||||||
for (auto const &prop : properties_) {
|
for (auto const &prop : properties_) {
|
||||||
const auto finding = instance.find(prop.first);
|
const auto finding = instance.find(prop.first);
|
||||||
if (instance.end() == finding) { // if the prop is not in the instance
|
if (instance.end() == finding) { // if the prop is not in the instance
|
||||||
const auto &defaultValue = prop.second->defaultValue(ptr, instance, e);
|
const auto &default_value = prop.second->default_value(ptr, instance, e);
|
||||||
if (!defaultValue.is_null()) { // if default value is available
|
if (!default_value.is_null()) { // if default value is available
|
||||||
patch.add((ptr / prop.first), defaultValue);
|
patch.add((ptr / prop.first), default_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1282,23 +1275,21 @@ std::shared_ptr<schema> schema::make(json &schema,
|
|||||||
auto id = uris.back().derive(attr.value().get<std::string>());
|
auto id = uris.back().derive(attr.value().get<std::string>());
|
||||||
sch = root->get_or_create_ref(id);
|
sch = root->get_or_create_ref(id);
|
||||||
|
|
||||||
const auto default_attr = schema.find("default");
|
|
||||||
if (default_attr != schema.end()) {
|
|
||||||
if (type_schema *type_sch = dynamic_cast<type_schema *>(sch.get())) {
|
|
||||||
// copy the referenced schema and modify the default value
|
|
||||||
auto schema_copy = std::make_shared<type_schema>(*type_sch);
|
|
||||||
schema_copy->set_default_value(default_attr.value());
|
|
||||||
sch = schema_copy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
schema.erase(attr);
|
schema.erase(attr);
|
||||||
|
|
||||||
|
// special case where break draft-7 and allow overriding of properties when a $ref is used
|
||||||
|
attr = schema.find("default");
|
||||||
|
if (attr != schema.end()) {
|
||||||
|
// copy the referenced schema and modify the default value
|
||||||
|
sch = std::make_shared<schema_ref>(*dynamic_cast<schema_ref *>(sch.get()));
|
||||||
|
sch->set_default_value(attr.value());
|
||||||
|
schema.erase(attr);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sch = std::make_shared<type_schema>(schema, root, uris);
|
sch = std::make_shared<type_schema>(schema, root, uris);
|
||||||
}
|
}
|
||||||
|
|
||||||
schema.erase("$schema");
|
schema.erase("$schema");
|
||||||
schema.erase("default");
|
|
||||||
schema.erase("title");
|
schema.erase("title");
|
||||||
schema.erase("description");
|
schema.erase("description");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ static const json quad_schema = R"(
|
|||||||
"height": {
|
"height": {
|
||||||
"$ref": "#/definitions/length"
|
"$ref": "#/definitions/length"
|
||||||
},
|
},
|
||||||
"depths": {
|
"depth": {
|
||||||
"$ref": "default_schema#/definitions/defaultLength"
|
"$ref": "default_schema#/definitions/defaultLength"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user