# HandlerWrapper GenServer: wraps a closure for use as a handler
defmodule HandlerWrapper do
use GenServer
def start_link(handler_fn) do
GenServer.start_link(__MODULE__, handler_fn)
end
def init(handler_fn) do
{:ok, handler_fn}
end
def handle_cast({:trait_call, _method, args_json, reply_id}, handler_fn) do
case Jason.decode(args_json) do
{:ok, args} ->
# Build request context from RequestData fields in args
try do
conn = build_conn(args)
response = handler_fn.(conn)
response_json = Jason.encode!(response)
Native.complete_trait_call(reply_id, response_json)
rescue
_e -> Native.complete_trait_call(reply_id, "{\"error\": \"handler error\"}")
end
{:error, _} ->
Native.complete_trait_call(reply_id, "{\"error\": \"json decode error\"}")
end
{:noreply, handler_fn}
end
# Convert RequestData JSON to request context struct
defp build_conn(args) do
%{{ conn_module }}{
path_params: args["path_params"] || %{},
query_params: args["query_params"] || %{},
headers: args["headers"] || %{},
cookies: args["cookies"] || %{},
body: args["body"],
raw_body: args["raw_body"],
method: args["method"] || "GET",
path: args["path"] || "/"
}
end
end