ref-schema: create a new ref-schema when default-value is present
Default-values on schemas with a $ref field are now stored within a new reference schema which links to the original reference schema. It contains the default value and keeps a strong reference (shared_ptr) to the original reference. Fixes #209
This commit is contained in:
parent
c6cb3d4c2d
commit
4f67636760
@ -65,6 +65,8 @@ class schema_ref : public schema
|
|||||||
{
|
{
|
||||||
const std::string id_;
|
const std::string id_;
|
||||||
std::weak_ptr<schema> target_;
|
std::weak_ptr<schema> target_;
|
||||||
|
std::shared_ptr<schema> target_strong_; // for references to references keep also the shared_ptr because
|
||||||
|
// no one else might use it after resolving
|
||||||
|
|
||||||
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
|
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
|
||||||
{
|
{
|
||||||
@ -95,7 +97,13 @@ public:
|
|||||||
: schema(root), id_(id) {}
|
: schema(root), id_(id) {}
|
||||||
|
|
||||||
const std::string &id() const { return id_; }
|
const std::string &id() const { return id_; }
|
||||||
void set_target(const std::shared_ptr<schema> &target) { target_ = target; }
|
|
||||||
|
void set_target(const std::shared_ptr<schema> &target, bool strong = false)
|
||||||
|
{
|
||||||
|
target_ = target;
|
||||||
|
if (strong)
|
||||||
|
target_strong_ = target;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -1277,13 +1285,17 @@ std::shared_ptr<schema> schema::make(json &schema,
|
|||||||
|
|
||||||
schema.erase(attr);
|
schema.erase(attr);
|
||||||
|
|
||||||
// special case where break draft-7 and allow overriding of properties when a $ref is used
|
// special case where we break draft-7 and allow overriding of properties when a $ref is used
|
||||||
attr = schema.find("default");
|
attr = schema.find("default");
|
||||||
if (attr != schema.end()) {
|
if (attr != schema.end()) {
|
||||||
// copy the referenced schema depending on the underlying type and modify the default value
|
// copy the referenced schema depending on the underlying type and modify the default value
|
||||||
if (auto *ref_sch = dynamic_cast<schema_ref *>(sch.get())) {
|
if (dynamic_cast<schema_ref *>(sch.get())) {
|
||||||
sch = std::make_shared<schema_ref>(*ref_sch);
|
// create a new reference schema use the original reference (which will be resolved later)
|
||||||
sch->set_default_value(attr.value());
|
// to store this overloaed default value #209
|
||||||
|
auto overloaded_ref_sch = std::make_shared<schema_ref>(uris[0].to_string(), root);
|
||||||
|
overloaded_ref_sch->set_target(sch, true);
|
||||||
|
overloaded_ref_sch->set_default_value(attr.value());
|
||||||
|
sch = overloaded_ref_sch;
|
||||||
} else if (auto *type_sch = dynamic_cast<type_schema *>(sch.get())) {
|
} else if (auto *type_sch = dynamic_cast<type_schema *>(sch.get())) {
|
||||||
sch = std::make_shared<type_schema>(*type_sch);
|
sch = std::make_shared<type_schema>(*type_sch);
|
||||||
sch->set_default_value(attr.value());
|
sch->set_default_value(attr.value());
|
||||||
|
|||||||
3
test/issue-209/CMakeLists.txt
Normal file
3
test/issue-209/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
add_test_simple_schema(Issue::209
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/entities.schema.json
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/instance.json)
|
||||||
8
test/issue-209/color.schema.json
Normal file
8
test/issue-209/color.schema.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://example.invalid/color.schema.json",
|
||||||
|
"title": "color",
|
||||||
|
"description": "X11/HTML/CSS color name as a JSON string",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [ "White", "Black", "Red" ]
|
||||||
|
}
|
||||||
16
test/issue-209/entities.schema.json
Normal file
16
test/issue-209/entities.schema.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://example.invalid/entities.schema.json",
|
||||||
|
"title": "Entities",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [ "name" ],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fg": { "$ref": "color.schema.json", "default": "Black" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
test/issue-209/instance.json
Normal file
10
test/issue-209/instance.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "player",
|
||||||
|
"fg": "White"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enemy",
|
||||||
|
"fg": "Red"
|
||||||
|
}
|
||||||
|
]
|
||||||
Loading…
Reference in New Issue
Block a user