@brief creates a diff as a JSON patch @sa https://json.nlohmann.me/api/basic_json/diff/
| 5028 | /// @brief creates a diff as a JSON patch |
| 5029 | /// @sa https://json.nlohmann.me/api/basic_json/diff/ |
| 5030 | JSON_HEDLEY_WARN_UNUSED_RESULT |
| 5031 | static basic_json diff(const basic_json& source, const basic_json& target, |
| 5032 | const string_t& path = "") |
| 5033 | { |
| 5034 | // the patch |
| 5035 | basic_json result(value_t::array); |
| 5036 | |
| 5037 | // if the values are the same, return an empty patch |
| 5038 | if (source == target) |
| 5039 | { |
| 5040 | return result; |
| 5041 | } |
| 5042 | |
| 5043 | if (source.type() != target.type()) |
| 5044 | { |
| 5045 | // different types: replace value |
| 5046 | result.push_back( |
| 5047 | { |
| 5048 | {"op", "replace"}, {"path", path}, {"value", target} |
| 5049 | }); |
| 5050 | return result; |
| 5051 | } |
| 5052 | |
| 5053 | switch (source.type()) |
| 5054 | { |
| 5055 | case value_t::array: |
| 5056 | { |
| 5057 | // first pass: traverse common elements |
| 5058 | std::size_t i = 0; |
| 5059 | while (i < source.size() && i < target.size()) |
| 5060 | { |
| 5061 | // recursive call to compare array values at index i |
| 5062 | auto temp_diff = diff(source[i], target[i], detail::concat<string_t>(path, '/', detail::to_string<string_t>(i))); |
| 5063 | result.insert(result.end(), temp_diff.begin(), temp_diff.end()); |
| 5064 | ++i; |
| 5065 | } |
| 5066 | |
| 5067 | // We now reached the end of at least one array |
| 5068 | // in a second pass, traverse the remaining elements |
| 5069 | |
| 5070 | // remove my remaining elements |
| 5071 | const auto end_index = static_cast<difference_type>(result.size()); |
| 5072 | while (i < source.size()) |
| 5073 | { |
| 5074 | // add operations in reverse order to avoid invalid |
| 5075 | // indices |
| 5076 | result.insert(result.begin() + end_index, object( |
| 5077 | { |
| 5078 | {"op", "remove"}, |
| 5079 | {"path", detail::concat<string_t>(path, '/', detail::to_string<string_t>(i))} |
| 5080 | })); |
| 5081 | ++i; |
| 5082 | } |
| 5083 | |
| 5084 | // add other remaining elements |
| 5085 | while (i < target.size()) |
| 5086 | { |
| 5087 | result.push_back( |