|
|
@@ -27,6 +27,7 @@
|
|
|
, jsonable_map/2
|
|
|
, binary_string/1
|
|
|
, deep_convert/3
|
|
|
+ , diff_maps/2
|
|
|
]).
|
|
|
|
|
|
-export_type([config_key/0, config_key_path/0]).
|
|
|
@@ -129,6 +130,27 @@ jsonable_map(Map) ->
|
|
|
jsonable_map(Map, JsonableFun) ->
|
|
|
deep_convert(Map, fun binary_string_kv/3, [JsonableFun]).
|
|
|
|
|
|
+-spec diff_maps(map(), map()) ->
|
|
|
+ #{added := [map()], identical := [map()], removed := [map()],
|
|
|
+ changed := [#{any() => {OldValue::any(), NewValue::any()}}]}.
|
|
|
+diff_maps(NewMap, OldMap) ->
|
|
|
+ InitR = #{identical => [], changed => [], removed => []},
|
|
|
+ {Result, RemInNew} =
|
|
|
+ lists:foldl(fun({OldK, OldV}, {Result0 = #{identical := I, changed := U, removed := D},
|
|
|
+ RemNewMap}) ->
|
|
|
+ Result1 = case maps:find(OldK, NewMap) of
|
|
|
+ error ->
|
|
|
+ Result0#{removed => [#{OldK => OldV} | D]};
|
|
|
+ {ok, NewV} when NewV == OldV ->
|
|
|
+ Result0#{identical => [#{OldK => OldV} | I]};
|
|
|
+ {ok, NewV} ->
|
|
|
+ Result0#{changed => [#{OldK => {OldV, NewV}} | U]}
|
|
|
+ end,
|
|
|
+ {Result1, maps:remove(OldK, RemNewMap)}
|
|
|
+ end, {InitR, NewMap}, maps:to_list(OldMap)),
|
|
|
+ Result#{added => RemInNew}.
|
|
|
+
|
|
|
+
|
|
|
binary_string_kv(K, V, JsonableFun) ->
|
|
|
case JsonableFun(K, V) of
|
|
|
drop -> drop;
|