accent/lib/accessible.ex
Simon Prévost bca59c4caa Initial commit 💥
2018-04-05 16:47:36 -04:00

54 lines
1.2 KiB
Elixir

defmodule Accessible do
@moduledoc false
defmacro __using__(_) do
quote location: :keep do
@behaviour Access
def fetch(struct, key), do: Map.fetch(struct, key)
def get(struct, key, default \\ nil) do
case struct do
%{^key => value} -> value
_else -> default
end
end
def put(struct, key, val) do
if Map.has_key?(struct, key) do
Map.put(struct, key, val)
else
struct
end
end
def delete(struct, key) do
put(struct, key, struct(__MODULE__)[key])
end
def get_and_update(struct, key, fun) when is_function(fun, 1) do
current = get(struct, key)
case fun.(current) do
{value, update} ->
{value, put(struct, key, update)}
:pop ->
{current, delete(struct, key)}
other ->
raise "the given function must return a two-element tuple or :pop, got: #{inspect(other)}"
end
end
def pop(struct, key, default \\ nil) do
val = get(struct, key, default)
updated = delete(struct, key)
{val, updated}
end
defoverridable fetch: 2, get: 3, put: 3, delete: 2, get_and_update: 3, pop: 3
end
end
end