From 397ada22d35cf2ebc168a48f264218c069f13d74 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 20 Apr 2016 16:52:00 +0200 Subject: [PATCH] implemented remove --- src/json.hpp | 26 +++++++++++++++++++++++-- src/json.hpp.re2c | 26 +++++++++++++++++++++++-- test/unit.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index acde03bf..de6c6ec1 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8969,6 +8969,18 @@ basic_json_parser_63: : reference_tokens(split(s)) {} + std::string pop_back() + { + if (reference_tokens.empty()) + { + throw std::domain_error("JSON pointer has no parent"); + } + + auto last = reference_tokens.back(); + reference_tokens.pop_back(); + return last; + } + private: /*! @brief create and return a reference to the pointed to value @@ -9420,7 +9432,7 @@ basic_json_parser_63: private: /// the reference tokens - const std::vector reference_tokens {}; + std::vector reference_tokens {}; }; //////////////////////////// @@ -9539,7 +9551,7 @@ basic_json_parser_63: const std::string op = it_op->second; const std::string path = it_path->second; - const json_pointer ptr(path); + json_pointer ptr(path); if (op == "add") { @@ -9552,6 +9564,16 @@ basic_json_parser_63: } else if (op == "remove") { + const auto last_path = ptr.pop_back(); + basic_json& parent = result.at(ptr); + if (parent.is_object()) + { + parent.erase(parent.find(last_path)); + } + else if (parent.is_array()) + { + parent.erase(parent.begin() + std::stoi(last_path)); + } } else if (op == "replace") { diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index d161f38d..073baf36 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -8279,6 +8279,18 @@ class basic_json : reference_tokens(split(s)) {} + std::string pop_back() + { + if (reference_tokens.empty()) + { + throw std::domain_error("JSON pointer has no parent"); + } + + auto last = reference_tokens.back(); + reference_tokens.pop_back(); + return last; + } + private: /*! @brief create and return a reference to the pointed to value @@ -8730,7 +8742,7 @@ class basic_json private: /// the reference tokens - const std::vector reference_tokens {}; + std::vector reference_tokens {}; }; //////////////////////////// @@ -8849,7 +8861,7 @@ class basic_json const std::string op = it_op->second; const std::string path = it_path->second; - const json_pointer ptr(path); + json_pointer ptr(path); if (op == "add") { @@ -8862,6 +8874,16 @@ class basic_json } else if (op == "remove") { + const auto last_path = ptr.pop_back(); + basic_json& parent = result.at(ptr); + if (parent.is_object()) + { + parent.erase(parent.find(last_path)); + } + else if (parent.is_array()) + { + parent.erase(parent.begin() + std::stoi(last_path)); + } } else if (op == "replace") { diff --git a/test/unit.cpp b/test/unit.cpp index 7b675462..6f9ad8f5 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -12421,6 +12421,55 @@ TEST_CASE("JSON patch") CHECK(doc.apply_patch(patch) == expected); } + SECTION("example A.3 - Removing an Object Member") + { + // An example target JSON document: + json doc = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // A JSON Patch document: + json patch = R"( + [ + { "op": "remove", "path": "/baz" } + ] + )"_json; + + // The resulting JSON document: + json expected = R"( + { "foo": "bar" } + )"_json; + + // check if patched value is as expected + CHECK(doc.apply_patch(patch) == expected); + } + + SECTION("example A.4 - Removing an Array Element") + { + // An example target JSON document: + json doc = R"( + { "foo": [ "bar", "qux", "baz" ] } + )"_json; + + // A JSON Patch document: + json patch = R"( + [ + { "op": "remove", "path": "/foo/1" } + ] + )"_json; + + // The resulting JSON document: + json expected = R"( + { "foo": [ "bar", "baz" ] } + )"_json; + + // check if patched value is as expected + CHECK(doc.apply_patch(patch) == expected); + } + SECTION("example A.5 - Replacing a Value") { // An example target JSON document: