Field-level Elixir input validation with error maps
Elixir
defmodule InputValidation do
@rules %{
name: &(is_binary(&1) and String.length(&1) in 2..50),
email: &(is_binary(&1) and String.contains?(&1, "@")),
age: &(is_integer(&1) and &1 in 18..130)
}
def validate(params, rules \\ @rules) do
errors =
Enum.reduce(rules, %{}, fn {field, check}, acc ->
case Map.fetch(params, field) do
:error -> Map.put(acc, field, "is required")
{:ok, value} -> if check.(value), do: acc, else: Map.put(acc, field, "is invalid")
end
end)
if map_size(errors) == 0, do: {:ok, params}, else: {:error, errors}
end
end