Packages
zoi
0.12.1
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, coerce: false]
def opts() do
Zoi.Opts.meta_opts()
|> Zoi.Opts.with_coerce()
end
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
coerce = Keyword.get(opts, :coerce, schema.coerce)
Enum.find(schema.values, fn {key, value} ->
if coerce do
input == value or input == key
else
input == value
end
end)
|> case do
nil ->
error(schema)
{key, _value} ->
{:ok, key}
end
end
defp error(schema) do
{:error, Zoi.Error.invalid_enum_value(schema.values, error: schema.meta.error)}
end
def type_spec(%Zoi.Types.Enum{values: values} = _schema, _opts) do
keys = Enum.map(values, fn {key, _value} -> key end)
cond do
Enum.all?(keys, &is_binary(&1)) ->
quote(do: binary())
Enum.any?(keys, &is_binary(&1)) ->
quote(do: any())
true ->
keys
|> Enum.reverse()
|> Enum.reduce("e(do: unquote(&1) | unquote(&2)))
end
end
end
defimpl Inspect do
def inspect(type, opts) do
symmetric_enum? = Enum.all?(type.values, fn {key, value} -> key == value end)
values =
if symmetric_enum? do
Enum.map(type.values, fn {_key, value} -> value end)
else
type.values
end
Zoi.Inspect.build(type, opts, values: values)
end
end
defimpl Zoi.JSONSchema.Encoder do
def encode(schema) do
%{type: :string, enum: Enum.map(schema.values, fn {_k, v} -> v end)}
end
end
end