Packages
zoi
0.16.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/intersection.ex
defmodule Zoi.Types.Intersection do
@moduledoc false
use Zoi.Type.Def, fields: [:schemas]
def new([], _opts) do
raise ArgumentError, "Intersection type must be receive a list of minimum 2 schemas"
end
def new([_one_element], _opts) do
raise ArgumentError, "Intersection type must be receive a list of minimum 2 schemas"
end
def new(schemas, opts) when is_list(schemas) do
apply_type(opts ++ [schemas: schemas])
end
def new(_schemas, _opts) do
raise ArgumentError, "Intersection type must be receive a list of minimum 2 schemas"
end
defimpl Zoi.Type do
def parse(%Zoi.Types.Intersection{schemas: schemas} = intersection, value, opts) do
Enum.reduce_while(schemas, nil, fn schema, _acc ->
ctx = Zoi.Context.new(schema, value)
opts = Keyword.put(opts, :ctx, ctx)
case Zoi.parse(schema, value, opts) do
{:ok, result} ->
{:cont, {:ok, result}}
{:error, reason} ->
{:halt, error(intersection, reason)}
end
end)
end
defp error(schema, type_error) do
if error = schema.meta.error do
{:error, Zoi.Error.custom_error(issue: {error, []})}
else
{:error, type_error}
end
end
end
# There is no direct representation of a intersection in Elixir types, so we use union `|`
defimpl Zoi.TypeSpec do
def spec(%Zoi.Types.Intersection{schemas: schemas}, opts) do
Enum.map(schemas, &Zoi.TypeSpec.spec(&1, opts))
|> Enum.reverse()
|> Enum.reduce("e(do: unquote(&1) | unquote(&2)))
end
end
defimpl Inspect do
import Inspect.Algebra
def inspect(type, opts) do
schemas_doc =
container_doc("[", type.schemas, "]", %Inspect.Opts{limit: 5}, fn
schema, _opts -> Inspect.inspect(schema, opts)
end)
Zoi.Inspect.build(type, opts, schemas: schemas_doc)
end
end
defimpl Zoi.JSONSchema.Encoder do
def encode(schema) do
%{allOf: Enum.map(schema.schemas, &Zoi.JSONSchema.Encoder.encode/1)}
end
end
defimpl Zoi.Describe.Encoder do
def encode(%{schemas: schemas}) do
Enum.map_join(schemas, " and ", &Zoi.Describe.Encoder.encode/1)
end
end
end