Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add patch_inplace function #3581

Merged
merged 3 commits into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions docs/examples/patch_inplace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>

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;
}
13 changes: 13 additions & 0 deletions docs/examples/patch_inplace.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Before
{
"baz": "qux",
"foo": "bar"
}

After
{
"baz": "boo",
"hello": [
"world"
]
}
1 change: 1 addition & 0 deletions docs/mkdocs/docs/api/basic_json/patch.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ is thrown. In any case, the original value is not changed: the patch is applied

- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
- [patch_inplace](patch_inplace.md) applies a JSON Patch without creating a copy of the document
- [merge_patch](merge_patch.md) applies a JSON Merge Patch

## Version history
Expand Down
63 changes: 63 additions & 0 deletions docs/mkdocs/docs/api/basic_json/patch_inplace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# <small>nlohmann::basic_json::</small>patch_inplace

```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

## 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.md), `patch_inplace` applies the operation "in place" and no copy of the JSON value is created. That makes it faster for large documents by avoiding the copy. However, the JSON value 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)
- [patch](patch.md) applies a JSON Merge Patch
- [merge_patch](merge_patch.md) applies a JSON Merge Patch
wolfv marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 10 additions & 6 deletions include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4641,13 +4641,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};

Expand Down Expand Up @@ -4911,7 +4909,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;
}

Expand Down Expand Up @@ -5049,7 +5054,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec

return result;
}

/// @}

////////////////////////////////
Expand Down
16 changes: 10 additions & 6 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -23566,7 +23571,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec

return result;
}

/// @}

////////////////////////////////
Expand Down