Packages
zoi
0.5.6
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.1
0.16.0
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.9.0-rc.1
0.9.0-rc.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
Zoi is a schema validation library for Elixir, designed to provide a simple and flexible way to define and validate data.
Current section
Files
Jump to
Current section
Files
lib/zoi/types/enum.ex
defmodule Zoi.Types.Enum do
@moduledoc false
use Zoi.Type.Def, fields: [:values, :enum_type]
def new(values, opts \\ []) when is_list(values) do
type = verify_type(values)
mapping =
Enum.map(values, fn
{key, value} ->
{key, value}
value ->
{value, value}
end)
apply_type(opts ++ [values: mapping, enum_type: type])
end
defp verify_type([{key, value} | _rest]) when is_atom(key) and is_binary(value) do
:atom_binary
end
defp verify_type([{key, value} | _rest]) when is_atom(key) and is_integer(value) do
:atom_integer
end
defp verify_type([value | _rest]) when is_atom(value) do
:atom
end
defp verify_type([value | _rest]) when is_binary(value) do
:binary
end
defp verify_type([value | _rest]) when is_integer(value) do
:integer
end
defp verify_type(_values) do
raise ArgumentError, "Invalid enum values"
end
defimpl Zoi.Type do
def parse(%Zoi.Types.Enum{} = schema, input, _opts) do
case parse_enum(schema, input) do
{:error, _reason} = error ->
error
nil ->
error(schema)
{key, _value} ->
{:ok, key}
end
end
defp parse_enum(schema, input) do
cond do
schema.enum_type in [:atom_binary, :binary] and is_binary(input) ->
compare_input(schema.values, input)
schema.enum_type in [:atom_integer, :integer] and is_integer(input) ->
compare_input(schema.values, input)
schema.enum_type == :atom and is_atom(input) ->
compare_input(schema.values, input)
true ->
error(schema)
end
end
defp compare_input(values, input) do
Enum.find(values, fn {_key, value} -> input == value end)
end
defp error(schema) do
options = stringify_enum(schema.values)
error =
schema.meta.error || "invalid option, must be one of: #{options}"
{:error, error}
end
defp stringify_enum(values) do
Enum.map_join(values, ", ", fn {_key, value} -> value end)
end
def type_spec(%Zoi.Types.Enum{values: values} = _schema, _opts) do
Enum.map(values, fn {key, _value} -> key end)
|> Enum.reverse()
|> Enum.reduce("e(do: unquote(&1) | unquote(&2)))
end
end
end