diff --git a/lib/diff/patch.ex b/lib/diff/patch.ex index 4a5a48c..c7a59d9 100644 --- a/lib/diff/patch.ex +++ b/lib/diff/patch.ex @@ -2,40 +2,32 @@ defmodule ExAudit.Patch do @doc """ Applies the patch to the given term """ - def patch(_, {:primitive_change, _, b}) do - b - end - - def patch(a, :not_changed) do - a - end + def patch(_, {:primitive_change, _, value}), do: value + def patch(value, :not_changed), do: value def patch(list, changes) when is_list(list) and is_list(changes) do changes |> Enum.reverse() |> Enum.reduce(list, fn - {:added_to_list, i, el}, list -> - List.insert_at(list, i, el) - - {:removed_from_list, i, _}, list -> - List.delete_at(list, i) - - {:changed_in_list, i, change}, list -> - List.update_at(list, i, &patch(&1, change)) + {:added_to_list, i, el}, list -> List.insert_at(list, i, el) + {:removed_from_list, i, _}, list -> List.delete_at(list, i) + {:changed_in_list, i, change}, list -> List.update_at(list, i, &patch(&1, change)) end) end def patch(map, changes) when is_map(map) and is_map(changes) do - changes - |> Enum.reduce(map, fn - {key, {:added, b}}, map -> - Map.put(map, key, b) - - {key, {:removed, _}}, map -> - Map.delete(map, key) + Enum.reduce(changes, map, fn + {key, {:added, value}}, map -> Map.put(map, key, value) + {key, {:removed, _}}, map -> Map.delete(map, key) + {key, {:changed, changes}}, map -> Map.update(map, key, nil, &patch(&1, changes)) + end) + end - {key, {:changed, changes}}, map -> - Map.update(map, key, nil, &patch(&1, changes)) + def patch(nil, changes) when is_map(changes) do + Enum.reduce(changes, %{}, fn + {key, {:added, value}}, map -> Map.put(map, key, value) + {key, {:removed, _}}, map -> Map.delete(map, key) + {key, {:changed, changes}}, map -> Map.put(map, key, patch(map, changes)) end) end end