Packages

delegate Access callbacks to another module

Current section

Files

Jump to
delegate_access lib delegate_access.ex
Raw

lib/delegate_access.ex

defmodule DelegateAccess do
@funs [fetch: 2, get: 3, get_and_update: 3, pop: 2]
defp delegate_access({:__aliases__, _, module_parts}) do
delegate_access(Module.concat(module_parts))
end
defp delegate_access(module) do
exports = module.__info__(:functions) |> Enum.filter(&(&1 in @funs)) |> Enum.into(%{})
fn fun, arity ->
case exports do
%{^fun => ^arity} ->
args = Macro.generate_arguments(arity, nil)
quote do
@impl Access
defdelegate unquote(fun)(unquote_splicing(args)), to: unquote(module)
defoverridable [{unquote(fun), unquote(arity)}]
end
_ ->
nil
end
end
end
defmacro __using__(opts) do
delegate = delegate_access(opts[:to] || Map)
only = opts[:only] || @funs
quote do
@behaviour Access
unquote(for {fun, arity} <- only do
delegate.(fun, arity)
end)
end
end
end