@brief creates a diff as a JSON patch @sa https://json.nlohmann.me/api/basic_json/diff/
| 4498 | /// @brief creates a diff as a JSON patch |
| 4499 | /// @sa https://json.nlohmann.me/api/basic_json/diff/ |
| 4500 | JSON_HEDLEY_WARN_UNUSED_RESULT |
| 4501 | static basic_json diff(const basic_json& source, const basic_json& target, |
| 4502 | const std::string& path = "") |
| 4503 | { |
| 4504 | // the patch |
| 4505 | basic_json result(value_t::array); |
| 4506 | |
| 4507 | // if the values are the same, return empty patch |
| 4508 | if (source == target) |
| 4509 | { |
| 4510 | return result; |
| 4511 | } |
| 4512 | |
| 4513 | if (source.type() != target.type()) |
| 4514 | { |
| 4515 | // different types: replace value |
| 4516 | result.push_back( |
| 4517 | { |
| 4518 | {"op", "replace"}, {"path", path}, {"value", target} |
| 4519 | }); |
| 4520 | return result; |
| 4521 | } |
| 4522 | |
| 4523 | switch (source.type()) |
| 4524 | { |
| 4525 | case value_t::array: |
| 4526 | { |
| 4527 | // first pass: traverse common elements |
| 4528 | std::size_t i = 0; |
| 4529 | while (i < source.size() && i < target.size()) |
| 4530 | { |
| 4531 | // recursive call to compare array values at index i |
| 4532 | auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i)); |
| 4533 | result.insert(result.end(), temp_diff.begin(), temp_diff.end()); |
| 4534 | ++i; |
| 4535 | } |
| 4536 | |
| 4537 | // We now reached the end of at least one array |
| 4538 | // in a second pass, traverse the remaining elements |
| 4539 | |
| 4540 | // remove my remaining elements |
| 4541 | const auto end_index = static_cast<difference_type>(result.size()); |
| 4542 | while (i < source.size()) |
| 4543 | { |
| 4544 | // add operations in reverse order to avoid invalid |
| 4545 | // indices |
| 4546 | result.insert(result.begin() + end_index, object( |
| 4547 | { |
| 4548 | {"op", "remove"}, |
| 4549 | {"path", path + "/" + std::to_string(i)} |
| 4550 | })); |
| 4551 | ++i; |
| 4552 | } |
| 4553 | |
| 4554 | // add other remaining elements |
| 4555 | while (i < target.size()) |
| 4556 | { |
| 4557 | result.push_back( |