Просмотр исходного кода

feat(map_lib): support emqx_map_lib:deep_merge/2

Shawn 4 лет назад
Родитель
Сommit
6d92d87ae7
1 измененных файлов с 18 добавлено и 0 удалено
  1. 18 0
      apps/emqx/src/emqx_map_lib.erl

+ 18 - 0
apps/emqx/src/emqx_map_lib.erl

@@ -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).