Current section
Files
Jump to
Current section
Files
lib/executer.ex
defmodule TalibEx.Executer do
@moduledoc false
defstruct [
:params,
args: [],
valid?: true,
error_message: nil
]
def new(params), do: %__MODULE__{params: Map.new(params)}
def load(token, name, type, opts \\ %{})
def load(%__MODULE__{valid?: false} = token, _name, _type, _opts), do: token
def load(%__MODULE__{params: params} = token, name, :double_array, %{default: default}) do
case Map.get(params, name, default) do
[_ | _] = list -> %{token | args: [list | token.args]}
[] -> add_error(token, "#{name} is an empty list")
nil -> add_error(token, required(name))
_ -> add_error(token, type(name, :list))
end
end
def load(%__MODULE__{params: params} = token, name, :integer, %{default: default} = opts) do
%{min: min, max: max} =
opts
|> Map.put_new(:min, nil)
|> Map.put_new(:max, nil)
case Map.get(params, name, default) do
nil ->
add_error(token, required(name))
integer
when is_integer(integer) and
(is_nil(min) or integer >= min) and
(is_nil(max) or integer <= max) ->
%{token | args: [integer | token.args]}
integer
when is_integer(integer) and is_number(min) and integer < min ->
add_error(token, "#{name} should be grater than #{min}")
integer
when is_integer(integer) and is_number(max) and integer > max ->
add_error(token, "#{name} should be less than #{min}")
_ ->
add_error(token, type(name, :integer))
end
end
def load(%__MODULE__{params: params} = token, name, :double, %{default: default} = opts) do
%{min: min, max: max} =
opts
|> Map.put_new(:min, nil)
|> Map.put_new(:max, nil)
case Map.get(params, name, default) do
nil ->
add_error(token, required(name))
number
when is_number(number) and
(is_nil(min) or number >= min) and
(is_nil(max) or number <= max) ->
%{token | args: [number | token.args]}
number
when is_number(number) and is_number(min) and number < min ->
add_error(token, "#{name} should be grater than #{min}")
number
when is_number(number) and is_number(max) and number > max ->
add_error(token, "#{name} should be less than #{min}")
_ ->
add_error(token, type(name, :number))
end
end
def load(%__MODULE__{params: params} = token, name, :ma_type, %{default: default}) do
case Map.get(params, name, default) do
value when value in ~w(sma ema wma dema tema trima kama mama t3)a ->
%{token | args: [value | token.args]}
_ ->
add_error(token, required(name))
end
end
def load(%__MODULE__{} = token, name, type, opts),
do: load(token, name, type, Map.put(opts, :default, nil))
def call(%__MODULE__{valid?: false, error_message: message}, _function), do: {:error, message}
def call(%__MODULE__{args: args}, function) do
args = Enum.reverse(args)
case apply(function, args) do
{:error, message} -> {:error, List.to_string(message)}
result -> result
end
end
defp type(name, type), do: "#{name} should be a #{type}"
defp required(name), do: "#{name} is required"
defp add_error(token, message), do: %{token | error_message: message, valid?: false}
end