mirror of
https://github.com/mirego/accent.git
synced 2024-08-17 06:50:31 +03:00
54 lines
1.2 KiB
Elixir
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
|