diff --git a/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_transformer.h b/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_transformer.h index f657051b5..282bcdc83 100644 --- a/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_transformer.h +++ b/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_transformer.h @@ -10,8 +10,9 @@ #include #include -#include // std::variant -#include // std::vector +#include // std::initializer_list +#include // std::variant +#include // std::vector namespace sourcemeta::jsontoolkit { @@ -68,6 +69,9 @@ class SOURCEMETA_JSONTOOLKIT_JSONSCHEMA_EXPORT SchemaTransformer { -> void; /// Remove an object property auto erase(const Pointer &path, const JSON::String &key) -> void; + /// Remove multiple object properties + auto erase_keys(const Pointer &path, std::initializer_list keys) + -> void; // For convenience @@ -81,6 +85,8 @@ class SOURCEMETA_JSONTOOLKIT_JSONSCHEMA_EXPORT SchemaTransformer { auto assign(const JSON::String &key, JSON &&value) -> void; /// Remove an object property auto erase(const JSON::String &key) -> void; + /// Remove multiple object properties + auto erase_keys(std::initializer_list keys) -> void; private: JSON &data; diff --git a/src/jsonschema/transformer.cc b/src/jsonschema/transformer.cc index bfd905d10..ae5016f30 100644 --- a/src/jsonschema/transformer.cc +++ b/src/jsonschema/transformer.cc @@ -51,6 +51,19 @@ auto sourcemeta::jsontoolkit::SchemaTransformer::erase( this->erase(sourcemeta::jsontoolkit::empty_pointer, key); } +auto sourcemeta::jsontoolkit::SchemaTransformer::erase_keys( + const sourcemeta::jsontoolkit::Pointer &path, + std::initializer_list keys) -> void { + for (const auto &key : keys) { + this->erase(path, key); + } +} + +auto sourcemeta::jsontoolkit::SchemaTransformer::erase_keys( + std::initializer_list keys) -> void { + this->erase_keys(sourcemeta::jsontoolkit::empty_pointer, keys); +} + auto sourcemeta::jsontoolkit::SchemaTransformer::assign( const sourcemeta::jsontoolkit::Pointer &path, const sourcemeta::jsontoolkit::JSON::String &key, diff --git a/test/jsonschema/jsonschema_transformer_test.cc b/test/jsonschema/jsonschema_transformer_test.cc index 8e23bf214..5c0f3d6f1 100644 --- a/test/jsonschema/jsonschema_transformer_test.cc +++ b/test/jsonschema/jsonschema_transformer_test.cc @@ -134,3 +134,51 @@ TEST(JSONSchema_transformer, erase_in_subobject) { EXPECT_EQ(std::get(traces.at(0)).pointer, sourcemeta::jsontoolkit::Pointer({"foo", "bar"})); } + +TEST(JSONSchema_transformer, erase_many) { + sourcemeta::jsontoolkit::JSON document = + sourcemeta::jsontoolkit::parse("{ \"foo\": 1, \"bar\": 2, \"baz\": 3 }"); + sourcemeta::jsontoolkit::SchemaTransformer transformer{document}; + transformer.erase_keys({"foo", "baz"}); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse("{ \"bar\": 2 }"); + const auto &traces{transformer.traces()}; + + EXPECT_EQ(document, expected); + EXPECT_EQ(traces.size(), 2); + + using namespace sourcemeta::jsontoolkit; + EXPECT_TRUE( + std::holds_alternative(traces.at(0))); + EXPECT_TRUE( + std::holds_alternative(traces.at(1))); + EXPECT_EQ(std::get(traces.at(0)).pointer, + sourcemeta::jsontoolkit::Pointer{"foo"}); + EXPECT_EQ(std::get(traces.at(1)).pointer, + sourcemeta::jsontoolkit::Pointer{"baz"}); +} + +TEST(JSONSchema_transformer, erase_many_in_subobject) { + sourcemeta::jsontoolkit::JSON document = sourcemeta::jsontoolkit::parse( + "{ \"foo\": { \"bar\": 1, \"baz\": 2, \"qux\": 3 } }"); + sourcemeta::jsontoolkit::SchemaTransformer transformer{document}; + transformer.erase_keys({"foo"}, {"bar", "qux"}); + + const sourcemeta::jsontoolkit::JSON expected = + sourcemeta::jsontoolkit::parse("{ \"foo\": { \"baz\": 2 } }"); + const auto &traces{transformer.traces()}; + + EXPECT_EQ(document, expected); + EXPECT_EQ(traces.size(), 2); + + using namespace sourcemeta::jsontoolkit; + EXPECT_TRUE( + std::holds_alternative(traces.at(0))); + EXPECT_TRUE( + std::holds_alternative(traces.at(1))); + EXPECT_EQ(std::get(traces.at(0)).pointer, + sourcemeta::jsontoolkit::Pointer({"foo", "bar"})); + EXPECT_EQ(std::get(traces.at(1)).pointer, + sourcemeta::jsontoolkit::Pointer({"foo", "qux"})); +}