implemented "move"
This commit is contained in:
parent
855cf2307b
commit
09e9f6dcd4
3 changed files with 152 additions and 60 deletions
75
src/json.hpp
75
src/json.hpp
|
@ -9526,6 +9526,44 @@ basic_json_parser_63:
|
||||||
throw std::domain_error("JSON patch must be an array of objects");
|
throw std::domain_error("JSON patch must be an array of objects");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto operation_add = [&result](json_pointer & ptr,
|
||||||
|
basic_json & value)
|
||||||
|
{
|
||||||
|
const auto last_path = ptr.pop_back();
|
||||||
|
basic_json& parent = result.at(ptr);
|
||||||
|
|
||||||
|
if (parent.is_object())
|
||||||
|
{
|
||||||
|
parent[last_path] = value;
|
||||||
|
}
|
||||||
|
else if (parent.is_array())
|
||||||
|
{
|
||||||
|
if (last_path == "-")
|
||||||
|
{
|
||||||
|
parent.push_back(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parent.insert(parent.begin() + std::stoi(last_path),
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto operation_remove = [&result](json_pointer & ptr)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (const auto& val : patch)
|
for (const auto& val : patch)
|
||||||
{
|
{
|
||||||
if (not val.is_object())
|
if (not val.is_object())
|
||||||
|
@ -9560,38 +9598,11 @@ basic_json_parser_63:
|
||||||
throw std::domain_error("'add' operation must have member 'value'");
|
throw std::domain_error("'add' operation must have member 'value'");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto last_path = ptr.pop_back();
|
operation_add(ptr, it_value->second);
|
||||||
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")
|
else if (op == "remove")
|
||||||
{
|
{
|
||||||
const auto last_path = ptr.pop_back();
|
operation_remove(ptr);
|
||||||
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")
|
else if (op == "replace")
|
||||||
{
|
{
|
||||||
|
@ -9610,7 +9621,11 @@ basic_json_parser_63:
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string from_path = it_from->second;
|
const std::string from_path = it_from->second;
|
||||||
const json_pointer from_ptr(from_path);
|
json_pointer from_ptr(from_path);
|
||||||
|
basic_json v = result[from_ptr];
|
||||||
|
|
||||||
|
operation_remove(from_ptr);
|
||||||
|
operation_add(ptr, v);
|
||||||
}
|
}
|
||||||
else if (op == "copy")
|
else if (op == "copy")
|
||||||
{
|
{
|
||||||
|
|
|
@ -8836,6 +8836,44 @@ class basic_json
|
||||||
throw std::domain_error("JSON patch must be an array of objects");
|
throw std::domain_error("JSON patch must be an array of objects");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto operation_add = [&result](json_pointer & ptr,
|
||||||
|
basic_json & value)
|
||||||
|
{
|
||||||
|
const auto last_path = ptr.pop_back();
|
||||||
|
basic_json& parent = result.at(ptr);
|
||||||
|
|
||||||
|
if (parent.is_object())
|
||||||
|
{
|
||||||
|
parent[last_path] = value;
|
||||||
|
}
|
||||||
|
else if (parent.is_array())
|
||||||
|
{
|
||||||
|
if (last_path == "-")
|
||||||
|
{
|
||||||
|
parent.push_back(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parent.insert(parent.begin() + std::stoi(last_path),
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto operation_remove = [&result](json_pointer & ptr)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (const auto& val : patch)
|
for (const auto& val : patch)
|
||||||
{
|
{
|
||||||
if (not val.is_object())
|
if (not val.is_object())
|
||||||
|
@ -8870,38 +8908,11 @@ class basic_json
|
||||||
throw std::domain_error("'add' operation must have member 'value'");
|
throw std::domain_error("'add' operation must have member 'value'");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto last_path = ptr.pop_back();
|
operation_add(ptr, it_value->second);
|
||||||
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")
|
else if (op == "remove")
|
||||||
{
|
{
|
||||||
const auto last_path = ptr.pop_back();
|
operation_remove(ptr);
|
||||||
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")
|
else if (op == "replace")
|
||||||
{
|
{
|
||||||
|
@ -8920,7 +8931,11 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string from_path = it_from->second;
|
const std::string from_path = it_from->second;
|
||||||
const json_pointer from_ptr(from_path);
|
json_pointer from_ptr(from_path);
|
||||||
|
basic_json v = result[from_ptr];
|
||||||
|
|
||||||
|
operation_remove(from_ptr);
|
||||||
|
operation_add(ptr, v);
|
||||||
}
|
}
|
||||||
else if (op == "copy")
|
else if (op == "copy")
|
||||||
{
|
{
|
||||||
|
|
|
@ -12521,6 +12521,68 @@ TEST_CASE("JSON patch")
|
||||||
CHECK(doc.apply_patch(patch) == expected);
|
CHECK(doc.apply_patch(patch) == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("example A.6 - Moving a Value")
|
||||||
|
{
|
||||||
|
// An example target JSON document:
|
||||||
|
json doc = R"(
|
||||||
|
{
|
||||||
|
"foo": {
|
||||||
|
"bar": "baz",
|
||||||
|
"waldo": "fred"
|
||||||
|
},
|
||||||
|
"qux": {
|
||||||
|
"corge": "grault"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)"_json;
|
||||||
|
|
||||||
|
// A JSON Patch document:
|
||||||
|
json patch = R"(
|
||||||
|
[
|
||||||
|
{ "op": "move", "from": "/foo/waldo", "path": "/qux/thud" }
|
||||||
|
]
|
||||||
|
)"_json;
|
||||||
|
|
||||||
|
// The resulting JSON document:
|
||||||
|
json expected = R"(
|
||||||
|
{
|
||||||
|
"foo": {
|
||||||
|
"bar": "baz"
|
||||||
|
},
|
||||||
|
"qux": {
|
||||||
|
"corge": "grault",
|
||||||
|
"thud": "fred"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)"_json;
|
||||||
|
|
||||||
|
// check if patched value is as expected
|
||||||
|
CHECK(doc.apply_patch(patch) == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("example A.7 - Moving a Value")
|
||||||
|
{
|
||||||
|
// An example target JSON document:
|
||||||
|
json doc = R"(
|
||||||
|
{ "foo": [ "all", "grass", "cows", "eat" ] }
|
||||||
|
)"_json;
|
||||||
|
|
||||||
|
// A JSON Patch document:
|
||||||
|
json patch = R"(
|
||||||
|
[
|
||||||
|
{ "op": "move", "from": "/foo/1", "path": "/foo/3" }
|
||||||
|
]
|
||||||
|
)"_json;
|
||||||
|
|
||||||
|
// The resulting JSON document:
|
||||||
|
json expected = R"(
|
||||||
|
{ "foo": [ "all", "cows", "eat", "grass" ] }
|
||||||
|
)"_json;
|
||||||
|
|
||||||
|
// check if patched value is as expected
|
||||||
|
CHECK(doc.apply_patch(patch) == expected);
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("example A.8 - Testing a Value: Success")
|
SECTION("example A.8 - Testing a Value: Success")
|
||||||
{
|
{
|
||||||
// An example target JSON document:
|
// An example target JSON document:
|
||||||
|
|
Loading…
Reference in a new issue