Packages
zoi
0.12.0
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/object.ex
defmodule Zoi.Types.Object do
@moduledoc false
use Zoi.Type.Def, fields: [:fields, :strict, :coerce, empty_values: []]
alias Zoi.Types.Meta
def opts() do
Zoi.Opts.complex_type_opts()
end
def new(fields, opts) when is_map(fields) or is_list(fields) do
fields =
fields
|> Enum.map(fn {key, type} ->
if type.meta.required == nil do
{key, Zoi.required(type)}
else
{key, type}
end
end)
opts =
Keyword.merge(
[strict: false, coerce: false],
opts
)
apply_type(opts ++ [fields: fields])
end
def new(_fields, _opts) do
raise ArgumentError, "object must receive a map"
end
defimpl Zoi.Type do
def parse(%Zoi.Types.Object{} = obj, input, opts) when is_map(input) do
Zoi.Types.KeyValue.parse(obj, input, opts)
end
def parse(schema, _, _) do
{:error, Zoi.Error.invalid_type(:object, error: schema.meta.error)}
end
def type_spec(%Zoi.Types.Object{fields: [{key, _val} | _rest]}, _opts) when is_binary(key) do
# If the keys are strings, there isn't a good way to represent that in typespecs
quote do: map()
end
def type_spec(%Zoi.Types.Object{fields: fields}, opts) do
fields
|> Enum.map(fn {key, type} ->
{key, Zoi.Type.type_spec(type, opts), type}
end)
|> Enum.map(fn {key, type_spec, type} ->
case Meta.required?(type.meta) do
true -> quote do: {required(unquote(key)), unquote(type_spec)}
_ -> quote do: {optional(unquote(key)), unquote(type_spec)}
end
end)
|> then("e(do: %{unquote_splicing(&1)}))
end
end
defimpl Inspect do
import Inspect.Algebra
def inspect(type, opts) do
fields_doc =
container_doc("%{", type.fields, "}", %Inspect.Opts{limit: 10}, fn
{key, schema}, _opts -> concat("#{key}: ", Inspect.inspect(schema, opts))
end)
Zoi.Inspect.build(type, opts, fields: fields_doc)
end
end
defimpl Zoi.JSONSchema.Encoder do
def encode(schema) do
%{
type: :object,
properties:
Enum.into(schema.fields, %{}, fn {key, value} ->
{key, Zoi.JSONSchema.Encoder.encode(value)}
end),
required:
Enum.flat_map(schema.fields, fn {k, v} ->
if Meta.required?(v.meta), do: [k], else: []
end),
additionalProperties: false
}
end
end
end