Packages

An extendable, customizable Elixir ETL framework

Current section

Files

Jump to
ex_etl_framework lib validator.ex
Raw

lib/validator.ex

defmodule ExEtlFramework.Validator do
def validate(data, schema) do
Enum.reduce_while(schema, {:ok, data}, fn {field, validators}, {:ok, acc} ->
case validate_field(data, field, validators) do
:ok -> {:cont, {:ok, acc}}
{:error, reason} -> {:halt, {:error, field, reason}}
{:error, failed_field, reason} -> {:halt, {:error, failed_field, reason}}
end
end)
end
defp validate_field(data, field, validators) when is_list(validators) do
value = Map.get(data, field)
Enum.reduce_while(validators, :ok, fn validator, _acc ->
case validator.(value) do
:ok -> {:cont, :ok}
{:error, reason} -> {:halt, {:error, reason}}
other ->
{:halt, other}
end
end)
end
def required(value) when is_nil(value), do: {:error, "Field is required"}
def required(_value), do: :ok
def type(expected_type) do
fn value ->
if is_nil(value) or is_type?(value, expected_type) do
:ok
else
{:error, "Expected type #{inspect(expected_type)}, got #{inspect(value)}"}
end
end
end
defp is_type?(value, String), do: is_binary(value)
defp is_type?(value, Integer), do: is_integer(value)
defp is_type?(value, Float), do: is_float(value)
defp is_type?(value, Number), do: is_number(value)
defp is_type?(value, Atom), do: is_atom(value)
defp is_type?(value, List), do: is_list(value)
defp is_type?(value, Boolean), do: is_boolean(value)
defp is_type?(value, Tuple), do: is_tuple(value)
defp is_type?(value, Map), do: is_map(value)
defp is_type?(value, Function), do: is_function(value)
defp is_type?(value, PID), do: is_pid(value)
defp is_type?(value, Port), do: is_port(value)
defp is_type?(value, Reference), do: is_reference(value)
defp is_type?(_value, Any), do: true
defp is_type?(value, expected_type), do: is_struct(value, expected_type)
end