Skip to content

Commit

Permalink
Add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
eproxus committed Sep 13, 2017
1 parent 65fb65e commit 454ebc9
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ logs
_build
.idea
rebar3.crashdump

doc/edoc-info
doc/erlang.png
doc/stylesheet.css
doc/*.html
57 changes: 55 additions & 2 deletions src/mapz.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,17 @@
-export([deep_merge/2]).
-export([deep_merge/3]).

-type path() :: [term()].
% A list of keys that are used to iterate deeper into a map of maps.

%--- API ----------------------------------------------------------------------

% @doc Returns a tuple `{ok,Value}', where Value is the value associated with
% `Path', or `error' if no value is associated with `Path' in `Map'.
%
% The call fails with a `{badmap,Map}' exception if `Map' is not a map, or with
% a `{badpath,Path}' exception if `Path' is not a path.
-spec deep_find(path(), map()) -> {ok, term()} | error.
deep_find(Path, Map) when is_list(Path), is_map(Map) ->
search(Map, Path,
fun(Value) -> {ok, Value} end,
Expand All @@ -22,6 +31,11 @@ deep_find(Path, Map) when is_map(Map) ->
deep_find(Path, Map) when is_list(Path) ->
error({badmap, Map}).

% @doc Returns value `Value' associated with `Path' if `Map' contains `Path'.
%
% The call fails with a `{badmap,Map}' exception if `Map' is not a map, or with
% a `{badpath,Path}' exception if `Path' is not a path.
-spec deep_get(path(), map()) -> term().
deep_get(Path, Map) when is_list(Path), is_map(Map) ->
search(Map, Path,
fun(Value) -> Value end,
Expand All @@ -32,6 +46,12 @@ deep_get(Path, Map) when is_map(Map) ->
deep_get(Path, Map) when is_list(Path) ->
error({badmap, Map}).

% @doc Returns value `Value' associated with `Path' if `Map' contains `Path'. If
% no value is associated with `Path', `Default' is returned.
%
% The call fails with a `{badmap,Map}' exception if `Map' is not a map, or with
% a `{badpath,Path}' exception if `Path' is not a path.
-spec deep_get(path(), map(), term()) -> term().
deep_get(Path, Map, Default) when is_list(Path), is_map(Map) ->
search(Map, Path,
fun(Value) -> Value end,
Expand All @@ -42,26 +62,59 @@ deep_get(Path, Map, _Default) when is_map(Map) ->
deep_get(Path, Map, _Default) when is_list(Path) ->
error({badmap, Map}).

% @doc Associates `Path' with value `Value' and inserts the association into map
% `Map2'. If path `Path' already exists in map `Map1', the old associated value
% is replaced by value `Value'. The function returns a new map `Map2' containing
% the new association and the old associations in `Map1'.
%
% The call fails with a `{badmap,Map}' exception if `Map' is not a map, or with
% a `{badpath,Path}' exception if `Path' is not a path.
-spec deep_put(path(), term(), map()) -> map().
deep_put(Path, Value, Map) when is_list(Path), is_map(Map) ->
update(Map, Path, {set, Value});
deep_put(Path, _Value, Map) when is_map(Map) ->
error({badpath, Path});
deep_put(Path, _Value, Map) when is_list(Path) ->
error({badmap, Map}).

% @doc Removes the `Path', if it exists, and its associated value from `Map1'
% and returns a new map `Map2' without path `Path'.
%
% The call fails with a `{badmap,Map}' exception if `Map' is not a map, or with
% a `{badpath,Path}' exception if `Path' is not a path.
-spec deep_remove(path(), map()) -> map().
deep_remove(Path, Map) when is_list(Path), is_map(Map) ->
update(Map, Path, delete);
deep_remove(Path, Map) when is_map(Map) ->
error({badpath, Path});
deep_remove(Path, Map) when is_list(Path) ->
error({badmap, Map}).

% @doc Merges a list of maps recursively into a single map. If a path exist in
% several maps, the value in the first nested map is superseded by the value in
% a following nested map.
%
% The call fails with a `{badmap,Map}' exception if `Map1' or `Map2' is not a
% map.
%
% @equiv deep_merge(fun (_, V) -> V end, #{}, Maps)
-spec deep_merge([map()]) -> map().
deep_merge([Map|Maps]) ->
deep_merge(fun (_, V) -> V end, Map, Maps).

deep_merge(First, Second) ->
deep_merge([First, Second]).
% @equiv deep_merge([Map1, Map2])
-spec deep_merge(map(), map()) -> map().
deep_merge(Map1, Map2) ->
deep_merge([Map1, Map2]).

% @doc Merges a list of maps `Maps' recursively into a single map `Target'. If a
% path exist in several maps, the function `Fun' is called with the previous and
% the conflicting value to resolve the conflict. The return value from the
% function is put into the resulting map.
%
% The call fails with a `{badmap,Map}' exception if any of the maps is not a
% map.
-spec deep_merge(fun((Old::term(), New::term()) -> term()), map(), map() | [map()]) -> map().
deep_merge(_Fun, Target, []) when is_map(Target) ->
Target;
deep_merge(Fun, Target, [From|Maps]) ->
Expand Down

0 comments on commit 454ebc9

Please sign in to comment.