diff --git a/docs/examples/patch_inplace.cpp b/docs/examples/patch_inplace.cpp new file mode 100644 index 000000000..62bc527d8 --- /dev/null +++ b/docs/examples/patch_inplace.cpp @@ -0,0 +1,34 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // the original document + json doc = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the patch + json patch = R"( + [ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} + ] + )"_json; + + // output original document + std::cout << "Before\n" << std::setw(4) << doc << std::endl; + + // apply the patch + doc.patch_inplace(patch); + + // output patched document + std::cout << "After\n" << std::setw(4) << doc << std::endl; +} diff --git a/docs/examples/patch_inplace.output b/docs/examples/patch_inplace.output new file mode 100644 index 000000000..9d31b8ba4 --- /dev/null +++ b/docs/examples/patch_inplace.output @@ -0,0 +1,13 @@ +Before +{ + "baz": "qux", + "foo": "bar" +} + +After +{ + "baz": "boo", + "hello": [ + "world" + ] +} diff --git a/docs/mkdocs/docs/api/basic_json/patch.md b/docs/mkdocs/docs/api/basic_json/patch.md index ce4574f2f..b3ef963f0 100644 --- a/docs/mkdocs/docs/api/basic_json/patch.md +++ b/docs/mkdocs/docs/api/basic_json/patch.md @@ -1,20 +1,13 @@ # nlohmann::basic_json::patch ```cpp -// (1) basic_json patch(const basic_json& json_patch) const; - -// (2) -void patch_inplace(const basic_json& json_patch) const; ``` [JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. -1. applies a JSON patch to a copy of the current object and returns the copy -2. applies a JSON patch in place and returns void - ## Parameters `json_patch` (in) @@ -22,13 +15,11 @@ the patch. ## Return value -1. patched document -2. void +patched document ## Exception safety -1. Strong guarantee: if an exception is thrown, there are no changes in the JSON value. -2. No guarantees, value may be corruted. +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. ## Exceptions diff --git a/docs/mkdocs/docs/api/basic_json/patch_inplace.md b/docs/mkdocs/docs/api/basic_json/patch_inplace.md new file mode 100644 index 000000000..1b95304d2 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json/patch_inplace.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::patch + +```cpp +void patch_inplace(const basic_json& json_patch) const; +``` + +[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to +a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. This function applies a JSON patch in place and returns void. + +## Parameters + +`json_patch` (in) +: JSON patch document + +## Return value + +void + +## Exception safety + +No guarantees, value may be corrupted by an unsuccessful patch operation. + +## Exceptions + +- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of + an array of objects. +- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g., + mandatory attributes are missing); example: `"operation add must have member path"`. +- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range. +- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch + could not be resolved successfully in the current JSON value; example: `"key baz not found"`. +- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent + ("add", "remove", "move") +- Throws [`out_of_range.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was + unsuccessful. + +## Complexity + +Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is +affected by the patch, the complexity can usually be neglected. + +## Notes + +Unlike `patch`, `patch_inplace` applies the operation "in place" and no copy of the json document is created. That makes it faster for large documents by avoiding the copy. However, the value of the json document might be corrupted if the function throws an exception. + +## Examples + +??? example + + The following code shows how a JSON patch is applied to a value. + + ```cpp + --8<-- "examples/patch_inplace.cpp" + ``` + + Output: + + ```json + --8<-- "examples/patch_inplace.output" + ``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) +- [merge_patch](merge_patch.md) applies a JSON Merge Patch diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index cffbd7dce..271a83a5c 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -23158,13 +23158,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name JSON Patch functions /// @{ - /// @brief applies a JSON patch + /// @brief applies a JSON patch in-place without copying the object /// @sa https://json.nlohmann.me/api/basic_json/patch/ - basic_json patch(const basic_json& json_patch) const + void patch_inplace(const basic_json& json_patch) { - // make a working copy to apply the patch to - basic_json result = *this; - + basic_json& result = *this; // the valid JSON Patch operations enum class patch_operations {add, remove, replace, move, copy, test, invalid}; @@ -23428,7 +23426,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } } + } + /// @brief applies a JSON patch to a copy of the current object + /// @sa https://json.nlohmann.me/api/basic_json/patch/ + basic_json patch(const basic_json& json_patch) const + { + basic_json result = *this; + result.patch_inplace(json_patch); return result; } @@ -23566,7 +23571,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /// @} ////////////////////////////////