Current section

Files

Jump to
gate lib gate.ex
Raw

lib/gate.ex

defmodule Gate do
alias Gate.Validator
alias Gate.Locale
def valid?(params, schema) when is_map(schema) do
validate(schema, params, %{}, %{})
end
def valid?(attribute, schema), do: Validator.validate(attribute, schema)
defp validate(schema, _params, errors, new_params) when schema == %{} do
if errors == %{} do
{:ok, new_params}
else
{:error, errors}
end
end
defp validate(schema, params, errors, new_params) do
key = schema |> Map.keys() |> List.first()
if Map.has_key?(params, key) do
if is_map(schema[key]) do
case validate(schema[key], params[key], %{}, %{}) do
{:ok, nested_params} ->
nested_valid(key, schema, params, errors, new_params, nested_params)
{:error, nested_errors} ->
nested_invalid(key, schema, params, errors, nested_errors)
end
else
case Validator.validate(params[key], schema[key]) do
true -> valid(key, schema, params, errors, new_params)
error -> invalid(key, schema, params, errors, error)
end
end
else
if optional?(schema[key]) do
validate(schema |> Map.delete(key), params, errors, new_params)
else
missing(key, schema, params, errors)
end
end
end
defp nested_valid(key, schema, params, errors, new_params, nested_params) do
validate(schema |> Map.delete(key), params, errors, new_params |> Map.put(key, nested_params))
end
defp nested_invalid(key, schema, params, errors, nested_errors) do
validate(schema |> Map.delete(key), params, errors |> Map.put(key, nested_errors), %{})
end
defp valid(key, schema, params, errors, new_params) do
validate(schema |> Map.delete(key), params, errors, new_params |> Map.put(key, params[key]))
end
defp invalid(key, schema, params, errors, error) do
validate(schema |> Map.delete(key), params, errors |> Map.put(key, error), %{})
end
defp missing(key, schema, params, errors) do
validate(
schema |> Map.delete(key),
params,
errors |> Map.put(key, Locale.get("missing")),
%{}
)
end
defp optional?(validations) when is_list(validations), do: Enum.member?(validations, :optional)
defp optional?(validation), do: validation == :optional
end