Current section

Files

Jump to
aja lib helpers custom_maps.ex
Raw

lib/helpers/custom_maps.ex

defmodule A.Helpers.CustomMaps do
@moduledoc false
@compile {:inline, get_and_update: 3, get_and_update!: 3, do_get_and_update: 4}
@doc false
def get_and_update(%map_module{} = custom_map, key, fun) do
current = map_module.get(custom_map, key)
do_get_and_update(custom_map, key, fun, current)
end
@doc false
def get_and_update!(%map_module{} = custom_map, key, fun) do
current = map_module.fetch!(custom_map, key)
do_get_and_update(custom_map, key, fun, current)
end
defp do_get_and_update(%map_module{} = custom_map, key, fun, current) do
case fun.(current) do
{get, update} ->
{get, map_module.put(custom_map, key, update)}
:pop ->
{current, map_module.delete(custom_map, key)}
other ->
raise "the given function must return a two-element tuple or :pop, got: #{inspect(other)}"
end
end
defmacro implement_inspect(module, prefix, suffix) do
quote do
import Inspect.Algebra
def inspect(custom_map, opts) do
open = color(unquote(prefix <> "%{"), :map, opts)
sep = color(",", :map, opts)
close = color(unquote("}" <> suffix), :map, opts)
as_list = unquote(module).to_list(custom_map)
container_doc(open, as_list, close, opts, traverse_fun(as_list, opts),
separator: sep,
break: :strict
)
end
defp traverse_fun(list, opts) do
if Inspect.List.keyword?(list) do
&Inspect.List.keyword/2
else
sep = color(" => ", :map, opts)
&to_map(&1, &2, sep)
end
end
defp to_map({key, value}, opts, sep) do
concat(concat(to_doc(key, opts), sep), to_doc(value, opts))
end
end
end
end