Current section

Files

Jump to
xcribe lib conn_parser.ex
Raw

lib/conn_parser.ex

defmodule Xcribe.ConnParser do
alias Xcribe.Request
def execute(conn, description \\ "sample request") do
route = identify_route(conn)
path = format_path(route.path, Map.keys(conn.path_params))
%Request{
action: Atom.to_string(route.plug_opts),
header_params: conn.req_headers,
controller: conn |> controller_module(),
description: description,
params: conn.params,
path: path,
path_params: conn.path_params,
query_params: conn.query_params,
request_body: conn.body_params,
resource: resource_name(path, route),
resource_group: resource_group(route),
resp_body: conn.resp_body,
resp_headers: conn.resp_headers,
status_code: conn.status,
verb: Atom.to_string(route.verb)
}
end
defp identify_route(conn) do
conn
|> router_module()
|> apply(:__routes__, [])
|> enum_find(conn)
end
defp enum_find(routes, conn) do
routes
|> Enum.find(fn route -> has_eql_values?(route, conn) end)
end
defp has_eql_values?(route, conn) do
route.plug == controller_module(conn) and route.plug_opts == action_atom(conn) and
route.verb == verb_atom(conn) and match_path?(route, conn)
end
defp match_path?(%{path: route_path}, %{request_path: conn_path}),
do: Regex.match?(regex_to(route_path), conn_path)
defp regex_to(path), do: ~r/#{replace_params(path)}/
defp replace_params(path), do: String.replace(path, ~r/\:\w+/, ".*")
defp router_module(%{private: %{phoenix_router: router}}), do: router
defp controller_module(%{private: %{phoenix_controller: controller}}), do: controller
defp action_atom(%{private: %{phoenix_action: action}}), do: action
defp resource_group(%{pipe_through: [head | _rest]}), do: head
defp resource_name(path, %{plug_opts: plug_opts}) do
action = "#{plug_opts}"
path
|> String.split("/")
|> Enum.filter(fn item -> item != action && Regex.match?(~r/^\w+$/, item) end)
|> Enum.join("_")
end
defp resource_name(%{helper: nil, plug: controller}),
do: resource_name_by_controller(controller)
defp resource_name(%{helper: name, plug_opts: action}),
do: name |> String.replace("_#{action}", "")
defp resource_name_by_controller(controller) do
~r/\.(\w+)Controller$/
|> Regex.run(to_string(controller))
|> List.last()
|> String.downcase()
end
defp verb_atom(%{method: verb}), do: verb |> String.downcase() |> String.to_atom()
defp format_path(path, params), do: Enum.reduce(params, path, &transform_param/2)
defp transform_param(param, path), do: String.replace(path, ":#{param}", "{#{param}}")
end