Current section

Files

Jump to
kanta lib kanta validator.ex
Raw

lib/kanta/validator.ex

defmodule Kanta.Validator do
@moduledoc """
Kanta configuration validator
"""
def validate(parent_key \\ nil, opts, validator)
def validate(_parent_key, opts, validator) when is_list(opts) and is_function(validator, 1) do
Enum.reduce_while(opts, :ok, fn opt, acc ->
case validator.(opt) do
:ok -> {:cont, acc}
{:error, _reason} = error -> {:halt, error}
{:unknown, field, module} -> {:halt, unknown_error(field, module)}
end
end)
end
def validate(parent_key, opts, _validator) do
{:error, "expected #{inspect(parent_key)} to be a list, got: #{inspect(opts)}"}
end
def validate!(opts, validator) do
with {:error, reason} <- validator.(opts), do: raise(ArgumentError, reason)
end
defp unknown_error({name, _value}, known), do: unknown_error(name, known)
defp unknown_error(name, module) when is_atom(module) do
name = to_string(name)
module
|> struct([])
|> Map.from_struct()
|> Enum.map(fn {known, _} -> {String.jaro_distance(name, to_string(known)), known} end)
|> Enum.sort(:desc)
|> case do
[{score, known} | _] when score > 0.7 ->
{:error, "unknown option :#{name}, did you mean :#{known}?"}
_ ->
{:error, "unknown option :#{name}"}
end
end
end