Current section

Files

Jump to
maru_swagger lib maru_swagger params_extractor.ex
Raw

lib/maru_swagger/params_extractor.ex

defmodule MaruSwagger.ParamsExtractor do
alias Maru.Builder.Parameter.Information, as: PI
alias Maru.Builder.Parameter.Dependent.Information, as: DI
defmodule NonGetBodyParamsGenerator do
def generate(param_list, path) do
{path_param_list, body_param_list} =
param_list |> MaruSwagger.ParamsExtractor.filter_information()
|> Enum.split_with(&(&1.attr_name in path))
[
format_body_params(body_param_list)
| format_path_params(path_param_list)
]
end
defp default_body do
%{name: "body", in: "body", description: "", required: false}
end
defp format_path_params(param_list) do
Enum.map(param_list, fn param ->
%{
name: param.param_key,
description: param.desc || "",
type: param.type,
required: param.required,
in: "path"
}
end)
end
defp format_body_params(param_list) do
param_list
|> Enum.map(&format_param/1)
|> case do
[] ->
default_body()
params ->
params = Enum.into(params, %{})
default_body()
|> put_in([:schema], %{})
|> put_in([:schema, :properties], params)
end
end
defp format_param(param) do
{param.param_key, do_format_param(param.type, param)}
end
defp do_format_param("float", param) do
%{type: "number", format: "float", description: param.desc || "", required: param.required}
end
defp do_format_param("map", param) do
%{type: "object", properties: param.children |> Enum.map(&format_param/1) |> Enum.into(%{})}
end
defp do_format_param("list", param) do
%{
type: "array",
items: %{
type: "object",
properties: param.children |> Enum.map(&format_param/1) |> Enum.into(%{})
}
}
end
defp do_format_param({:list, type}, param) do
%{type: "array", items: do_format_param(type, param)}
end
defp do_format_param(type, param) do
%{description: param.desc || "", type: type, required: param.required}
end
end
defmodule NonGetFormDataParamsGenerator do
def generate(param_list, path) do
param_list
|> MaruSwagger.ParamsExtractor.filter_information()
|> Enum.map(fn param ->
%{
name: param.param_key,
description: param.desc || "",
type: param.type,
required: param.required,
in: (param.attr_name in path && "path") || "formData"
}
end)
end
end
alias Maru.Router
def extract_params(%Router{method: :get, path: path, parameters: parameters}, _config) do
for %PI{} = param <- parameters do
%{
name: param.param_key,
description: param.desc || "",
required: param.required,
type: param.type,
in: (param.attr_name in path && "path") || "query"
}
end
end
def extract_params(%Router{method: :get}, _config), do: []
def extract_params(%Router{parameters: []}, _config), do: []
def extract_params(%Router{parameters: param_list, path: path}, config) do
param_list = filter_information(param_list)
generator =
if config.force_json do
NonGetBodyParamsGenerator
else
case judge_adapter(param_list) do
:body -> NonGetBodyParamsGenerator
:form_data -> NonGetFormDataParamsGenerator
end
end
generator.generate(param_list, path)
end
defp judge_adapter([]), do: :form_data
defp judge_adapter([%{type: "list"} | _]), do: :body
defp judge_adapter([%{type: "map"} | _]), do: :body
defp judge_adapter([%{type: {:list, _}} | _]), do: :body
defp judge_adapter([_ | t]), do: judge_adapter(t)
def filter_information(param_list) do
Enum.filter(param_list, fn
%PI{} -> true
%DI{} -> true
_ -> false
end)
|> flatten_dependents
end
def flatten_dependents(param_list, force_optional \\ false) do
Enum.reduce(param_list, [], fn
%PI{} = i, acc when force_optional ->
do_append(acc, %{i | required: false})
%PI{} = i, acc ->
do_append(acc, i)
%DI{children: children}, acc ->
flatten_dependents(children, true)
|> Enum.reduce(acc, fn i, deps ->
do_append(deps, i)
end)
end)
end
defp do_append(param_list, i) do
Enum.any?(param_list, fn param ->
param.param_key == i.param_key
end)
|> case do
true -> param_list
false -> param_list ++ [i]
end
end
end