Packages

Elixir library for building Telegram bots with macro-based API

Current section

Files

Jump to
telegram_ex lib builders effect.ex
Raw

lib/builders/effect.ex

defmodule TelegramEx.Effect do
@moduledoc """
Execution container used by effect-aware builders.
An effect carries the current handler context together with either an error or
an optional result that can be converted back to a handler result with
`to_result/1`.
"""
@type t :: %__MODULE__{
ctx: map(),
result: term() | nil,
error: term() | nil
}
defstruct [:ctx, :result, :error]
def new(ctx) do
%__MODULE__{ctx: ctx, result: nil, error: nil}
end
def wrap(%__MODULE__{} = effect), do: effect
def wrap(ctx), do: new(ctx)
def to_result(%__MODULE__{error: nil, result: nil}), do: :ok
def to_result(%__MODULE__{error: nil, result: result}), do: result
def to_result(%__MODULE__{error: reason}), do: {:error, reason}
def to_result(result), do: result
def map_ctx(%__MODULE__{ctx: ctx, error: nil} = effect, fun) when is_function(fun, 1) do
%__MODULE__{effect | ctx: fun.(ctx)}
end
def map_ctx(%__MODULE__{} = effect, _fun), do: effect
def then(%__MODULE__{ctx: ctx} = effect, fun) do
case effect do
%__MODULE__{error: nil} ->
case fun.(ctx) do
{:ok, new_ctx} -> %__MODULE__{effect | ctx: new_ctx}
{:error, reason} -> %__MODULE__{effect | error: reason}
unknown -> %__MODULE__{effect | error: {:invalid_return_value, unknown}}
end
_ ->
effect
end
end
end