|
|
@@ -19,6 +19,7 @@
|
|
|
, deep_get/3
|
|
|
, deep_find/2
|
|
|
, deep_put/3
|
|
|
+ , deep_merge/2
|
|
|
, safe_atom_key_map/1
|
|
|
, unsafe_atom_key_map/1
|
|
|
]).
|
|
|
@@ -60,6 +61,23 @@ deep_put([Key | KeyPath], Map, Config) ->
|
|
|
SubMap = deep_put(KeyPath, maps:get(Key, Map, #{}), Config),
|
|
|
Map#{Key => SubMap}.
|
|
|
|
|
|
+%% #{a => #{b => 3, c => 2}, d => 4}
|
|
|
+%% = deep_merge(#{a => #{b => 1, c => 2}, d => 4}, #{a => #{b => 3}}).
|
|
|
+-spec deep_merge(map(), map()) -> map().
|
|
|
+deep_merge(BaseMap, NewMap) ->
|
|
|
+ NewKeys = maps:keys(NewMap) -- maps:keys(BaseMap),
|
|
|
+ MergedBase = maps:fold(fun(K, V, Acc) ->
|
|
|
+ case maps:find(K, NewMap) of
|
|
|
+ error ->
|
|
|
+ Acc#{K => V};
|
|
|
+ {ok, NewV} when is_map(V), is_map(NewV) ->
|
|
|
+ Acc#{K => deep_merge(V, NewV)};
|
|
|
+ {ok, NewV} ->
|
|
|
+ Acc#{K => NewV}
|
|
|
+ end
|
|
|
+ end, #{}, BaseMap),
|
|
|
+ maps:merge(MergedBase, maps:with(NewKeys, NewMap)).
|
|
|
+
|
|
|
unsafe_atom_key_map(Map) ->
|
|
|
covert_keys_to_atom(Map, fun(K) -> binary_to_atom(K, utf8) end).
|
|
|
|