Current section
Files
Jump to
Current section
Files
lib/litmus.ex
defmodule Litmus do
@moduledoc """
Litmus is a data validation library for Elixir.
"""
alias Litmus.Type
@doc """
Validates and converts data based on a schema.
## Examples
iex> Litmus.validate(%{"id" => "123"}, %{"id" => %Litmus.Type.Number{}})
{:ok, %{"id" => 123}}
iex> Litmus.validate(%{"id" => "asdf"}, %{"id" => %Litmus.Type.Number{}})
{:error, "id must be a number"}
"""
@spec validate(map, map) :: {:ok, map} | {:error, String.t()}
def validate(data, schema) do
case validate_allowed_params(data, schema) do
:ok -> validate_schema(data, schema)
{:error, msg} -> {:error, msg}
end
end
@spec validate_allowed_params(map, map) :: :ok | {:error, String.t()}
defp validate_allowed_params(data, schema) do
result = Map.keys(data) -- Map.keys(schema)
case result do
[] -> :ok
[field | _rest] -> {:error, "#{field} is not allowed"}
end
end
@spec validate_schema(map, map) :: {:ok, map} | {:error, String.t()}
defp validate_schema(data, schema) do
Enum.reduce_while(schema, {:ok, data}, fn {field, type}, {:ok, modified_data} ->
case Type.validate(type, field, modified_data) do
{:error, msg} ->
{:halt, {:error, msg}}
{:ok, new_data} ->
{:cont, {:ok, new_data}}
end
end)
end
end