Current section
Files
Jump to
Current section
Files
lib/phantom/resource_plug.ex
defmodule Phantom.ResourcePlug do
@moduledoc false
@behaviour Plug
import Plug.Conn
alias Phantom.Request
alias Phantom.Resource
alias Phantom.Session
@impl Plug
def init(opts), do: opts
@impl Plug
def call(fake_conn, _opts) do
session = %{
fake_conn.assigns.session
| request: %{fake_conn.assigns.session.request | spec: fake_conn.assigns.resource_template}
}
handler = fake_conn.assigns.resource_template.handler
function = fake_conn.assigns.resource_template.function
args =
if function_exported?(handler, function, 3) do
[fake_conn.path_params, session, fake_conn]
else
[fake_conn.path_params, session]
end
result =
try do
apply(handler, function, args)
rescue
_e in FunctionClauseError ->
{:error, Phantom.Request.resource_not_found(%{uri: fake_conn.assigns.uri}),
fake_conn.assigns.session}
end
assign(
fake_conn,
:result,
wrap(result, fake_conn.assigns.uri, fake_conn.assigns.session)
)
end
defp wrap({:error, reason}, _uri, session) do
{:error, reason, session}
end
defp wrap({:error, _reason, %Session{}} = result, _uri, _session), do: result
defp wrap(nil, uri, session) do
{:error, Request.resource_not_found(%{uri: uri}), session}
end
defp wrap({:noreply, %Session{}} = result, _uri, _session), do: result
defp wrap({:reply, nil, %Session{} = session}, uri, _session) do
{:error, Request.resource_not_found(%{uri: uri}), session}
end
defp wrap({:reply, %{code: code, message: _} = error, %Session{} = session}, _uri, _session)
when is_integer(code) and code < 0 do
{:error, error, session}
end
defp wrap({:reply, results, %Session{} = session}, _uri, _session) do
{:reply, Resource.response(results), session}
end
defmodule NotFound do
@moduledoc false
@behaviour Plug
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
result = Phantom.Request.resource_not_found(%{uri: conn.assigns.uri})
assign(conn, :result, {:error, result, conn.assigns.session})
end
end
end