defmodule FieldComparator do
@moduledoc """
Prepare validators to compare the input fields
"""
def prepare(data, validators, validator_mappings) do
validators
|> Enum.map(fn [path, path_to_value, validator] ->
{path, prepare_validator(validator, path_to_data(path_to_value, data), validator_mappings)}
end)
end
defp prepare_validator(validator, data, mappings) do
validator
|> Enum.map(fn
{validator_name, validator_options} ->
{validator_name,
get_validator(validator_name, mappings).to_comparator(data, validator_options)}
validator_name ->
{validator_name, get_validator(validator_name, mappings).to_comparator(data, nil)}
end)
end
defp path_to_data([path_part | []], %{} = data), do: Map.get(data, path_part)
defp path_to_data([path_part | path], %{} = data),
do: path_to_data(path, Map.get(data, path_part))
defp path_to_data([elem], data) when is_list(data) and is_integer(elem),
do: Enum.fetch!(data, elem)
defp get_validator(name, validators) when is_atom(name), do: validators[name]
end