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_;
|
||||
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
|
||||
{
|
||||
@ -95,7 +97,13 @@ public:
|
||||
: schema(root), id_(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
|
||||
@ -1277,13 +1285,17 @@ std::shared_ptr<schema> schema::make(json &schema,
|
||||
|
||||
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");
|
||||
if (attr != schema.end()) {
|
||||
// copy the referenced schema depending on the underlying type and modify the default value
|
||||
if (auto *ref_sch = dynamic_cast<schema_ref *>(sch.get())) {
|
||||
sch = std::make_shared<schema_ref>(*ref_sch);
|
||||
sch->set_default_value(attr.value());
|
||||
if (dynamic_cast<schema_ref *>(sch.get())) {
|
||||
// create a new reference schema use the original reference (which will be resolved later)
|
||||
// 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())) {
|
||||
sch = std::make_shared<type_schema>(*type_sch);
|
||||
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