diff --git a/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h b/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h index bd6dd9a8a..37060e8a0 100644 --- a/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h +++ b/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h @@ -128,6 +128,10 @@ class SOURCEMETA_JSONTOOLKIT_JSONSCHEMA_EXPORT FlatFileSchemaResolver { const std::optional &default_id = std::nullopt) -> const std::string &; + // Change the identifier of a registered schema + auto reidentify(const std::string &schema, const std::string &new_identifier) + -> void; + /// Attempt to resolve a schema auto operator()(std::string_view identifier) const -> std::optional; @@ -139,8 +143,8 @@ class SOURCEMETA_JSONTOOLKIT_JSONSCHEMA_EXPORT FlatFileSchemaResolver { /// Represent an entry in the resolver struct Entry { - const std::filesystem::path path; - const std::optional default_dialect; + std::filesystem::path path; + std::optional default_dialect; }; private: diff --git a/src/jsonschema/resolver.cc b/src/jsonschema/resolver.cc index 59ce1d08d..61c405d5b 100644 --- a/src/jsonschema/resolver.cc +++ b/src/jsonschema/resolver.cc @@ -107,6 +107,15 @@ auto FlatFileSchemaResolver::add( return result.first->first; } +auto FlatFileSchemaResolver::reidentify(const std::string &schema, + const std::string &new_identifier) + -> void { + const auto result{this->schemas.find(schema)}; + assert(result != this->schemas.cend()); + this->schemas.insert_or_assign(new_identifier, std::move(result->second)); + this->schemas.erase(result); +} + auto FlatFileSchemaResolver::operator()(std::string_view identifier) const -> std::optional { const std::string string_identifier{identifier}; diff --git a/test/jsonschema/jsonschema_flat_file_resolver_test.cc b/test/jsonschema/jsonschema_flat_file_resolver_test.cc index 433a94bc4..876e20138 100644 --- a/test/jsonschema/jsonschema_flat_file_resolver_test.cc +++ b/test/jsonschema/jsonschema_flat_file_resolver_test.cc @@ -169,3 +169,30 @@ TEST(JSONSchema_FlatFileSchemaResolver, iterators) { EXPECT_EQ(entries.at(0).path, schema_path); EXPECT_FALSE(entries.at(0).default_dialect.has_value()); } + +TEST(JSONSchema_FlatFileSchemaResolver, reidentify) { + sourcemeta::jsontoolkit::FlatFileSchemaResolver resolver; + const auto schema_path{std::filesystem::path{SCHEMAS_PATH} / + "2020-12-id.json"}; + const auto &identifier{resolver.add(schema_path)}; + EXPECT_EQ(identifier, "https://www.sourcemeta.com/2020-12-id.json"); + EXPECT_TRUE( + resolver("https://www.sourcemeta.com/2020-12-id.json").has_value()); + EXPECT_EQ(resolver("https://www.sourcemeta.com/2020-12-id.json").value(), + sourcemeta::jsontoolkit::from_file(schema_path)); + + resolver.reidentify("https://www.sourcemeta.com/2020-12-id.json", + "https://example.com"); + + EXPECT_FALSE( + resolver("https://www.sourcemeta.com/2020-12-id.json").has_value()); + EXPECT_TRUE(resolver("https://example.com").has_value()); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse(R"JSON({ + "$id": "https://example.com", + "$schema": "https://json-schema.org/draft/2020-12/schema" + })JSON"); + + EXPECT_EQ(resolver("https://example.com").value(), expected); +}