Current section
Files
Jump to
Current section
Files
lib/conn.ex
defmodule GenRouter.Conn do
@moduledoc """
Structure which represents connection with Telegram bot.
Inspired by %Plug.Conn{}, adapted for bots.
Attributes:
* __skip__: system buffer to keep track of skipped scopes;
* path: route to controller which should handle this object;
* params: payload which will be passed to controller;
* assigns: non-parsed data assigned by a system (auth, etc);
* scope: local scope of current request, clears for each new route;
* code: response code, we use common HTTP codes, currently only 200 is supported.
* response: response payload, usually JSON
"""
defstruct [
__skip__: %{},
path: "/",
params: %{},
assigns: %{},
scope: %{},
code: nil,
response: nil
]
@type t :: %GenRouter.Conn{}
@doc """
Build Conn object with system fields
"""
@spec build(module(), map()) :: t
def build(router_module, %{path: path, params: params, assigns: assigns, scope: scope}) do
skip_router_scopes = Enum.reduce(router_module.scopes(), %{}, &(Map.put(&2, &1, false)))
%GenRouter.Conn{
__skip__: skip_router_scopes,
path: path,
params: params,
assigns: assigns,
scope: scope
}
end
@doc """
Assign variable to current request.
"""
@spec assign(t, atom(), any()) :: t
def assign(%GenRouter.Conn{assigns: assigns} = conn, key, value) do
assigns = Map.put(assigns, key, value)
%{conn | assigns: assigns}
end
@doc """
Update state and complete the current request.
"""
@spec complete(t, String.t | nil, map(), integer()) :: t
def complete(conn, response \\ nil, scope \\ %{}, code \\ 200)
def complete(%GenRouter.Conn{} = conn, response, scope, code) when is_map(scope) and is_integer(code) do
%{conn | response: response, scope: scope, code: code}
end
@doc """
Put the next path after the current request.
"""
@spec forward(t, String.t, map(), Keyword.t) :: t
def forward(%GenRouter.Conn{} = conn, path \\ "/", scope \\ %{}, opts \\ []) when is_bitstring(path) do
default_router =
Application.get_env(:gen_router, GenRouter.Conn)
|> Keyword.fetch!(:default_router)
router_module = Keyword.get(opts, :router_module, default_router)
%{conn | path: path, scope: scope, code: nil}
|> router_module.do_match(opts)
end
end