Current section
Files
Jump to
Current section
Files
lib/rollex/validator.ex
defmodule Rollex.Validator do
@moduledoc false
@max_tokens 1_000
@max_sides 1_000_000
@max_quantity 10_000
def validate({:error, _} = input), do: input
def validate({:ok, lexed_input}), do: _do_validations(lexed_input)
defp _do_validations([]), do: {:error, "Empty input!"}
defp _do_validations([%Rollex.Tokens.End{}]), do: {:error, "Empty input!"}
defp _do_validations(input) when is_list(input) do
if Enum.count_until(input, @max_tokens + 1) > @max_tokens do
{:error, "Input too large (max tokens is #{@max_tokens})!"}
else
input
|> _check_sides_and_quantity
|> _return_validation_results(input)
end
end
defp _return_validation_results(:ok, input), do: {:ok, input}
defp _return_validation_results(error, _input), do: error
defp _check_sides_and_quantity(input, side_acc \\ 0, quantity_acc \\ 0)
defp _check_sides_and_quantity({:error, _} = input, _side_acc, _quantity_acc), do: input
defp _check_sides_and_quantity(_, side_acc, _quantity_acc) when side_acc > @max_sides do
{:error, "Too many sides on an input die! (Max sides is #{@max_sides})"}
end
defp _check_sides_and_quantity(_, _side_acc, quantity_acc) when quantity_acc > @max_quantity do
{:error, "Too many dice to roll! (Max dice quantity is #{@max_quantity})"}
end
defp _check_sides_and_quantity([%Rollex.Tokens.End{}], _side_acc, _quantity_acc), do: :ok
defp _check_sides_and_quantity([token | tail], sides_acc, quantity_acc) do
if Map.get(token, :is_dice) == true do
_check_sides_and_quantity(
tail,
max(sides_acc, token.sides),
quantity_acc + token.quantity
)
else
_check_sides_and_quantity(tail, sides_acc, quantity_acc)
end
end
end