From 855cf2307bb7c4ac874cb5eaac74f1c4abf01428 Mon Sep 17 00:00:00 2001 From: Niels Date: Sun, 24 Apr 2016 16:51:06 +0200 Subject: [PATCH] extended "add" to cope with arrays --- src/json.hpp | 20 +++++++++++++++++++- src/json.hpp.re2c | 20 +++++++++++++++++++- test/unit.cpp | 28 +++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index de6c6ec1..c1bf6648 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -9560,7 +9560,25 @@ basic_json_parser_63: throw std::domain_error("'add' operation must have member 'value'"); } - result[ptr] = it_value->second; + const auto last_path = ptr.pop_back(); + basic_json& parent = result.at(ptr); + + if (parent.is_object()) + { + parent[last_path] = it_value->second; + } + else if (parent.is_array()) + { + if (last_path == "-") + { + parent.push_back(it_value->second); + } + else + { + parent.insert(parent.begin() + std::stoi(last_path), + it_value->second); + } + } } else if (op == "remove") { diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 073baf36..aa02bbea 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -8870,7 +8870,25 @@ class basic_json throw std::domain_error("'add' operation must have member 'value'"); } - result[ptr] = it_value->second; + const auto last_path = ptr.pop_back(); + basic_json& parent = result.at(ptr); + + if (parent.is_object()) + { + parent[last_path] = it_value->second; + } + else if (parent.is_array()) + { + if (last_path == "-") + { + parent.push_back(it_value->second); + } + else + { + parent.insert(parent.begin() + std::stoi(last_path), + it_value->second); + } + } } else if (op == "remove") { diff --git a/test/unit.cpp b/test/unit.cpp index 6f9ad8f5..277daed1 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -12421,6 +12421,29 @@ TEST_CASE("JSON patch") CHECK(doc.apply_patch(patch) == expected); } + SECTION("example A.2 - Adding an Array Element") + { + // An example target JSON document: + json doc = R"( + { "foo": [ "bar", "baz" ] } + )"_json; + + // A JSON Patch document: + json patch = R"( + [ + { "op": "add", "path": "/foo/1", "value": "qux" } + ] + )"_json; + + // The resulting JSON document: + json expected = R"( + { "foo": [ "bar", "qux", "baz" ] } + )"_json; + + // check if patched value is as expected + CHECK(doc.apply_patch(patch) == expected); + } + SECTION("example A.3 - Removing an Object Member") { // An example target JSON document: @@ -12616,9 +12639,12 @@ TEST_CASE("JSON patch") // an existing object, nor a member of an existing array. CHECK_THROWS_AS(doc.apply_patch(patch), std::out_of_range); - CHECK_THROWS_WITH(doc.apply_patch(patch), "unresolved reference token 'bat'"); + CHECK_THROWS_WITH(doc.apply_patch(patch), "key 'baz' not found"); } + // A.13. Invalid JSON Patch Document + // not applicable + SECTION("example A.14 - Escape Ordering") { // An example target JSON document: