Current section

Files

Jump to
validate lib validate.ex
Raw

lib/validate.ex

defmodule Validate do
@moduledoc """
Validate, validate incoming requests in an easy to reason-about way.
"""
@doc """
Validate.validate/2, the entry point for validation.
Takes in a struct. Returns either:
`{:ok, data}` or `{:error, errors}`
Data returned is filtered out to only keys provided in rules
"""
def validate(params, rules) do
{data, errors} =
Enum.reduce(rules, {%{}, %{}}, fn {key, item_rules}, {data, errors} ->
value = Map.get(params, key)
res = Enum.reduce(item_rules, {:ok, nil}, &evaluate_validator(value, &1, &2))
case res do
{:ok, x} ->
{Map.put(data, key, x), errors}
{:error, msg} ->
{data, Map.put(errors, key, msg)}
{:skip} ->
{data, errors}
end
end)
result(data, errors)
end
defp evaluate_validator(_value, _validator, {:skip} = acc), do: acc
defp evaluate_validator(value, validator, _acc), do: validator.(value)
defp result(data, errors) when map_size(errors) == 0, do: {:ok, data}
defp result(data, errors), do: {:error, errors}
end