Packages
zoi
0.6.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/tuple.ex
defmodule Zoi.Types.Tuple do
@moduledoc false
use Zoi.Type.Def, fields: [:fields, :length]
def new(fields, opts) when is_tuple(fields) do
fields = Tuple.to_list(fields)
apply_type(Keyword.merge(opts, fields: fields, length: length(fields)))
end
def new(_fields, _opts) do
raise ArgumentError, "must be a tuple"
end
defimpl Zoi.Type do
def parse(schema, input, opts) when is_tuple(input) do
input = Tuple.to_list(input)
if length(input) != schema.length do
error(schema)
else
parse_fields(schema, input, opts)
end
end
def parse(schema, _, _) do
error(schema)
end
defp parse_fields(schema, input, opts) do
schema.fields
|> Enum.with_index()
|> Enum.reduce({[], []}, fn {field, index}, {parsed, errors} ->
case Zoi.parse(field, Enum.at(input, index), opts) do
{:ok, value} ->
{[value | parsed], errors}
{:error, err} ->
error = Enum.map(err, &Zoi.Error.add_path(&1, [index]))
{parsed, Zoi.Errors.merge(errors, error)}
end
end)
|> then(fn {parsed, errors} ->
if errors == [] do
{:ok,
parsed
|> Enum.reverse()
|> List.to_tuple()}
else
{:error, errors}
end
end)
end
defp error(schema) do
{:error,
schema.meta.error || "invalid type: must be a tuple with #{schema.length} elements"}
end
def type_spec(%Zoi.Types.Tuple{fields: fields}, opts) do
field_specs = Enum.map(fields, &Zoi.Type.type_spec(&1, opts))
{:{}, [], field_specs}
end
end
end