mirror of
https://github.com/nlohmann/json.git
synced 2026-10-12 17:37:15 +00:00
support JSON Merge Patch (RFC 7396) diff creation (#4965)
* support JSON Merge Patch (RFC 7396) diff creation The JSON merge patch document format describes the set of modifications to a resource's content, that more closely mimics the syntax of the resource being modified. However, and in contrast to JSON Patch (RFC 6902), a JSON Merge Patch cannot express certain modifications, e.g., changing an array element at a specific index, or setting a specific object value to null. The null value in a JSON Merge Patch is used to remove the key from the object. The diff algorithm is not part of the RFC 7396, but it was tested against all examples provided, plus additional cases on how null values are handled. Signed-off-by: Luís Murta <luis@murta.dev> * improve algorithm efficiency Signed-off-by: Luís Murta <luis@murta.dev> * fix inconsistent nulls and empty arrays Also add CHECKs for the patch, documentation and run `make amalgamate`. Signed-off-by: Luís Murta <luis@murta.dev> * documentation cleanups Signed-off-by: Luís Murta <luis@murta.dev> * add an iterative fallback to merge_diff Bound the recursion depth like diff() and merge_patch(), and test values nested past the bound. Signed-off-by: Luís Murta <luis@murta.dev> * address the remaining review comments Signed-off-by: Luís Murta <luis@murta.dev> * move multi-line raw strings out of CHECK macros GCC 4.8/5, ICPC and NVHPC mis-tokenize multi-line raw string literals inside macro arguments, breaking the build or the parsed JSON. Signed-off-by: Luís Murta <luis@murta.dev> --------- Signed-off-by: Luís Murta <luis@murta.dev>
This commit is contained in:
1 parent
e8b747e4bc
commit
40a62947d3
12 files changed
+1541
-2
No files matched your search
@@ -567,9 +567,9 @@ TEST_CASE("Regression tests for extended diagnostics")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Better diagnostics past the descent bound of update() and merge_patch()")
|
||||
TEST_CASE("Better diagnostics past the descent bound of update(), merge_patch() and merge_diff()")
|
||||
{
|
||||
// Both merge objects nested more than detail::recursion_depth_limit()
|
||||
// All three handle objects nested more than detail::recursion_depth_limit()
|
||||
// (128) levels deep without recursing; the values they add or replace
|
||||
// there must still know their parents.
|
||||
// The values are built rather than parsed, so that the expected messages
|
||||
@@ -615,4 +615,19 @@ TEST_CASE("Better diagnostics past the descent bound of update() and merge_patch
|
||||
CHECK_THROWS_WITH_AS(p->at("x").at(0), expected_x.c_str(), json::type_error);
|
||||
CHECK_THROWS_WITH_AS(p->at("y").at(0), expected_y.c_str(), json::type_error);
|
||||
}
|
||||
|
||||
SECTION("merge_diff()")
|
||||
{
|
||||
// target and patch differ only in their innermost members, so the
|
||||
// diff of the two is nested as deeply: {"a": ... {"x": null, "y": 2}}
|
||||
const json diff = json::merge_diff(target, patch); // NOLINT(readability-suspicious-call-argument)
|
||||
|
||||
const json* p = &diff;
|
||||
for (std::size_t i = 0; i < depth; ++i)
|
||||
{
|
||||
p = &p->at("a");
|
||||
}
|
||||
CHECK(p->at("x").is_null());
|
||||
CHECK_THROWS_WITH_AS(p->at("y").at(0), expected_y.c_str(), json::type_error);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user