Packages
maru
0.9.4
0.14.0-pre.1
0.13.2
0.13.1
0.13.0
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
REST-like API micro-framework for elixir inspired by grape.
Current section
Files
Jump to
Current section
Files
lib/maru/builder/params.ex
defmodule Maru.Builder.Params do
@moduledoc """
Parse and build param_content block.
"""
alias Maru.Router.Param
alias Maru.Router.Validator
@doc false
defmacro use(param) when is_atom(param) do
quote do
params = @shared_params[unquote(param)]
Module.eval_quoted __MODULE__, params, [], __ENV__
end
end
defmacro use(params) do
quote do
for i <- unquote(params) do
params = @shared_params[i]
Module.eval_quoted __MODULE__, params, [], __ENV__
end
end
end
@doc """
Define a param should be present.
"""
defmacro requires(attr_name) do
quote do
@param_context @param_context ++ [
parse_options |> Map.merge(%{
attr_name: unquote(attr_name),
required: true,
children: [],
})
]
end
end
defmacro requires(attr_name, options, [do: block]) do
options = Keyword.merge([type: :list], options) |> escape_options
quote do
param_context = @param_context
@param_context []
unquote(block)
@param_context param_context ++ [
parse_options(unquote options) |> Map.merge(%{
attr_name: unquote(attr_name),
required: true,
children: @param_context,
})
]
end
end
defmacro requires(attr_name, [do: block]) do
options = [type: :list]
quote do
param_context = @param_context
@param_context []
unquote(block)
@param_context param_context ++ [
parse_options(unquote options) |> Map.merge(%{
attr_name: unquote(attr_name),
required: true,
children: @param_context,
})
]
end
end
defmacro requires(attr_name, options) do
options = options |> escape_options
quote do
@param_context @param_context ++ [
parse_options(unquote options) |> Map.merge(%{
attr_name: unquote(attr_name),
required: true,
children: [],
})
]
end
end
@doc """
Define a params group.
"""
defmacro group(group_name, options \\ [], [do: block]) do
options = Keyword.merge([type: :list], options) |> escape_options
quote do
param_context = @param_context
@param_context []
unquote(block)
@param_context param_context ++ [
parse_options(unquote options) |> Map.merge(%{
attr_name: unquote(group_name),
required: true,
children: @param_context,
})
]
end
end
@doc """
Define a param should be present or not.
"""
defmacro optional(attr_name) do
quote do
@param_context @param_context ++ [
parse_options |> Map.merge(%{
attr_name: unquote(attr_name),
required: false,
children: [],
})
]
end
end
defmacro optional(attr_name, options, [do: block]) do
options = Keyword.merge([type: :list], options) |> escape_options
quote do
param_context = @param_context
@param_context []
unquote(block)
@param_context param_context ++ [
parse_options(unquote options) |> Map.merge(%{
attr_name: unquote(attr_name),
required: false,
children: @param_context,
})
]
end
end
defmacro optional(attr_name, [do: block]) do
options = [type: :list]
quote do
param_context = @param_context
@param_context []
unquote(block)
@param_context param_context ++ [
parse_options(unquote options) |> Map.merge(%{
attr_name: unquote(attr_name),
required: false,
children: @param_context,
})
]
end
end
defmacro optional(attr_name, options) do
options = options |> escape_options
quote do
@param_context @param_context ++ [
parse_options(unquote options) |> Map.merge(%{
attr_name: unquote(attr_name),
required: false,
children: [],
})
]
end
end
def parse_options, do: %Param{}
def parse_options(options), do: parse_options(options, %Param{})
def parse_options([], result), do: result
def parse_options([{:type, v} | t], result) do
value =
case v do
{:__aliases__, _, [t]} -> t |> to_string |> Maru.Utils.lower_underscore |> String.to_atom
t when is_atom(t) -> t
end
parse_options(t, %{result | parser: value})
end
def parse_options([{:coerce_with, v} | t], result) do
value =
case v do
nil -> nil
{:__aliases__, _, [module]} -> module |> to_string |> Maru.Utils.lower_underscore |> String.to_atom
c when is_atom(c) -> c
{:fn, _, _}=c -> c
{:&, _, _}=c -> c |> Code.eval_quoted |> elem(0)
end
parse_options(t, %{result | coerce_with: value})
end
def parse_options([{k, _}=h | t], result) when k in [:default, :desc, :source] do
m = [h] |> Enum.into(%{})
result = result |> Map.merge(m)
parse_options(t, result)
end
def parse_options([h | t], %Param{validators: validators}=result) do
parse_options(t, %{result | validators: validators ++ [h]})
end
defp escape_options(options) do
options |> Enum.map(fn
{key, value} when key in [:coerce_with, :type] -> {key, value |> Macro.escape}
kv -> kv
end)
end
@actions [:mutually_exclusive, :exactly_one_of, :at_least_one_of]
Module.eval_quoted __MODULE__, (for action <- @actions do
quote do
@doc "Validator: #{unquote action}"
defmacro unquote(action)(attr_names) do
action = unquote(action)
quote do
@param_context @param_context ++ [
%Validator{action: unquote(action), attr_names: unquote(attr_names)}
]
end
end
end
end)
end