defmodule Sorcery.Utils.Maps do @doc """ Like `mkdir -p`, but for elixir maps. Safely does put_in, assuming nothing but maps all the way down. """ def put_in_p(m, [hd], value) do Map.put(m, hd, value) end def put_in_p(m, [hd | tl], value) do submap = Map.get(m, hd, %{}) |> put_in_p(tl, value) Map.put(m, hd, submap) end def delete_in(m, [hd]) do Map.delete(m, hd) end def delete_in(m, [hd | tl]) do submap = Map.get(m, hd, %{}) |> delete_in(tl) Map.put(m, hd, submap) end def deep_merge(left, right) do Map.merge(left, right, &deep_resolve/3) end # Key exists in both maps, and both values are maps as well. # These can be merged recursively. defp deep_resolve(_key, left = %{}, right = %{}) do deep_merge(left, right) end # Key exists in both maps, but at least one of the values is # NOT a map. We fall back to standard merge behavior, preferring # the value on the right. defp deep_resolve(_key, _left, right) do right end end