Current section
Files
Jump to
Current section
Files
src/optic_maps.erl
%%%-------------------------------------------------------------------
%%% @doc
%%% A set of optics specific to maps.
%%% @end
%%%-------------------------------------------------------------------
-module(optic_maps).
%% API
-export([all/0,
all/1,
keys/0,
keys/1,
values/0,
values/1,
associations/0,
associations/1,
key/1,
key/2,
association/1,
association/2]).
%%%===================================================================
%%% API
%%%===================================================================
-spec all() -> optic:optic().
all() ->
values().
-spec all(optic:extend_options()) -> optic:optic().
all(Options) ->
values(Options).
-spec keys() -> optic:optic().
keys() ->
keys(#{}).
-spec keys(optic:extend_options()) -> optic:optic().
keys(Options) ->
Fold = fun (Fun, Acc, Map) when is_map(Map) ->
{ok, maps:fold(fun (Key, _Value, InnerAcc) ->
Fun(Key, InnerAcc)
end,
Acc,
Map)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
MapFold = fun (Fun, Acc, Map) when is_map(Map) ->
{ok, maps:fold(fun (Key, Value, {InnerMap, InnerAcc}) ->
{NewKey, NewAcc} = Fun(Key, InnerAcc),
{InnerMap#{NewKey=>Value}, NewAcc}
end,
{#{}, Acc},
Map)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
New = fun (_Data, _Template) ->
#{}
end,
Optic = optic:new(MapFold, Fold),
optic:'%extend'(Optic, Options, New).
-spec values() -> optic:optic().
values() ->
values(#{}).
-spec values(optic:extend_options()) -> optic:optic().
values(Options) ->
Fold = fun (Fun, Acc, Map) when is_map(Map) ->
{ok, maps:fold(fun (_Key, Value, InnerAcc) ->
Fun(Value, InnerAcc)
end,
Acc,
Map)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
MapFold = fun (Fun, Acc, Map) when is_map(Map) ->
{ok, maps:fold(fun (Key, Value, {InnerMap, InnerAcc}) ->
{NewValue, NewAcc} = Fun(Value, InnerAcc),
{InnerMap#{Key=>NewValue}, NewAcc}
end,
{#{}, Acc},
Map)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
New = fun (_Data, _Template) ->
#{}
end,
Optic = optic:new(MapFold, Fold),
optic:'%extend'(Optic, Options, New).
-spec associations() -> optic:optic().
associations() ->
associations(#{}).
-spec associations(optic:extend_options()) -> optic:optic().
associations(Options) ->
Fold = fun (Fun, Acc, Map) when is_map(Map) ->
{ok, maps:fold(fun (Key, Value, InnerAcc) ->
Fun({Key, Value}, InnerAcc)
end,
Acc,
Map)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
MapFold = fun (Fun, Acc, Map) when is_map(Map) ->
{ok, maps:fold(fun (Key, Value, {InnerMap, InnerAcc}) ->
{{NewKey, NewValue}, NewAcc} = Fun({Key, Value}, InnerAcc),
{InnerMap#{NewKey=>NewValue}, NewAcc}
end,
{#{}, Acc},
Map)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
New = fun (_Data, _Template) ->
#{}
end,
Optic = optic:new(MapFold, Fold),
optic:'%extend'(Optic, Options, New).
-spec key(term()) -> optic:optic().
key(Key) ->
key(Key, #{}).
-spec key(term(), optic:extend_options()) -> optic:optic().
key(Key, Options) ->
Fold = fun (Fun, Acc, #{Key:=Value}) ->
{ok, Fun(Value, Acc)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
MapFold = fun (Fun, Acc, #{Key:=Value} = Map) when is_map(Map) ->
{NewValue, NewAcc} = Fun(Value, Acc),
{ok, {Map#{Key:=NewValue}, NewAcc}};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
New = fun (Map, Template) when is_map(Map) ->
Map#{Key=>Template};
(_Data, Template) ->
#{Key=>Template}
end,
Optic = optic:new(MapFold, Fold),
optic:'%extend'(Optic, Options, New).
-spec association(term()) -> optic:optic().
association(Key) ->
association(Key, #{}).
-spec association(term(), optic:extend_options()) -> optic:optic().
association(Key, Options) ->
Fold = fun (Fun, Acc, #{Key:=Value}) ->
{ok, Fun({Key, Value}, Acc)};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
MapFold = fun (Fun, Acc, #{Key:=Value} = Map) when is_map(Map) ->
{{NewKey, NewValue}, NewAcc} = Fun({Key, Value}, Acc),
{ok, {(maps:remove(Key, Map))#{NewKey=>NewValue}, NewAcc}};
(_Fun, _Acc, _Data) ->
{error, undefined}
end,
New = fun (Map, Template) when is_map(Map) ->
Map#{Key=>Template};
(_Data, Template) ->
#{Key=>Template}
end,
Optic = optic:new(MapFold, Fold),
optic:'%extend'(Optic, Options, New).