Skip to content

Commit

Permalink
Avoid crash when updating a nil map
Browse files Browse the repository at this point in the history
  • Loading branch information
simoncocking committed Aug 12, 2022
1 parent 404f174 commit 92dffd5
Showing 1 changed file with 16 additions and 24 deletions.
40 changes: 16 additions & 24 deletions lib/diff/patch.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 92dffd5

Please sign in to comment.