Packages
zoi
0.18.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, 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
end
defimpl Zoi.TypeSpec do
def spec(%Zoi.Types.Enum{values: values}, _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
defimpl Zoi.Describe.Encoder do
def encode(%{values: values}) do
"#{Enum.map_join(values, " | ", fn {_key, value} -> parse_enum_spec(value) end)}"
end
defp parse_enum_spec(value) when is_atom(value), do: "`:#{value}`"
defp parse_enum_spec(value), do: "`#{inspect(value)}`"
end
end