Current section

Files

Jump to
mazurka lib mazurka resource param.ex
Raw

lib/mazurka/resource/param.ex

defmodule Mazurka.Resource.Param do
defmacro param(name, opts \\ []) do
Mazurka.Compiler.Utils.register(__MODULE__, name, opts)
end
@doc false
def compile_global(params, _env) do
params = params
|> Enum.map(&compile_param/1)
quote do
defstruct unquote(params)
end
end
def compile(params, _env) do
Enum.reduce(params, [], &compile_assign/2)
end
defp compile_param({{name, _, _}, _opts}) when is_atom(name) do
compile_param({name, nil})
end
defp compile_param({name, _opts}) when is_atom(name) do
{name, nil}
end
defp compile_assign({name, opts}, acc) when is_atom(name) do
compile_assign({Macro.var(name, nil), opts}, acc)
end
defp compile_assign({name, [do: block]}, acc) do
expr = quote do
unquote(Macro.var(:value, nil)) = Params.get(unquote(name_to_binary(name)))
unquote(block)
end
[quote do
unquote(name) = unquote(expr)
end | acc]
end
defp compile_assign({name, _}, acc) do
[quote do
unquote(name) = Params.get(unquote(name_to_binary(name)))
end | acc]
end
defp name_to_binary({name, _meta, _context}) when is_atom(name) do
to_string(name)
end
defp name_to_binary(name) when is_atom(name) do
to_string(name)
end
@doc false
def format(ast, type \\ :prop) do
Mazurka.Compiler.Utils.postwalk(ast, fn
({{:., _, [{:__aliases__, _, [:Params]}, :get]}, _, []}) ->
get(type)
({{:., _, [params, :get]}, _, []}) when params in [:Params, Elixir.Params, __MODULE__] ->
get(type)
({{:., _, [{:__aliases__, _, [:Params]}, :get]}, _, [name]}) ->
get(name, type)
({{:., _, [params, :get]}, _, [name]}) when params in [:Params, Elixir.Params, __MODULE__] ->
get(name, type)
(other) ->
other
end)
end
defp get(:prop) do
{:etude_prop, [], [:params]}
end
defp get(:conn) do
quote do
^^Mazurka.Resource.Param.get()
end
end
defp get(name, :prop) do
quote do
^Mazurka.Runtime.get_param(unquote(get(:prop)), unquote(name))
end
end
defp get(name, :conn) do
quote do
^^Mazurka.Resource.Param.get(unquote(name))
end
end
@doc false
def get([], conn, _parent, _ref, _attrs) do
params = Map.get(conn.private, :mazurka_params)
{:ok, params}
end
def get([name], conn, _parent, _ref, _attrs) do
params = Map.get(conn.private, :mazurka_params)
val = Map.get(params, name)
normalized = if val == nil, do: :undefined, else: URI.decode(val)
{:ok, normalized}
end
end