Packages
zoi
0.18.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/codec.ex
defmodule Zoi.Types.Codec do
@moduledoc false
use Zoi.Type.Def, fields: [:from, :to, :decode, :encode]
def opts() do
Zoi.Opts.meta_opts()
|> Zoi.Types.Extend.new(
decode:
Zoi.Types.Any.new(
description:
"A 1-arity function that transforms from the `from` schema to the `to` schema."
),
encode:
Zoi.Types.Any.new(
description:
"A 1-arity function that transforms from the `to` schema to the `from` schema."
)
)
end
def new(opts, from, to) do
{decode, opts} = Keyword.pop!(opts, :decode)
{encode, opts} = Keyword.pop!(opts, :encode)
validate_function!(:decode, decode)
validate_function!(:encode, encode)
apply_type([from: from, to: to, decode: decode, encode: encode] ++ opts)
end
defp validate_function!(name, fun) do
unless is_function(fun, 1) do
raise ArgumentError,
"expected :#{name} to be a 1-arity function, got: #{inspect(fun)}"
end
end
def encode(%__MODULE__{} = codec, input, opts \\ []) do
with {:ok, validated_input} <- Zoi.parse(codec.to, input, opts),
{:ok, encoded} <- apply_encode(codec, validated_input) do
Zoi.parse(codec.from, encoded, opts)
end
end
defp apply_encode(codec, value) do
case codec.encode.(value) do
{:ok, encoded} -> {:ok, encoded}
{:error, reason} -> {:error, [Zoi.Error.new(message: reason)]}
encoded -> {:ok, encoded}
end
end
defimpl Zoi.Type do
def parse(schema, input, opts) do
with {:ok, validated_input} <- Zoi.parse(schema.from, input, opts),
{:ok, decoded} <- apply_decode(schema, validated_input) do
Zoi.parse(schema.to, decoded, opts)
end
end
defp apply_decode(schema, value) do
case schema.decode.(value) do
{:error, reason} -> {:error, Zoi.Error.new(message: reason)}
{:ok, decoded} -> {:ok, decoded}
decoded -> {:ok, decoded}
end
end
end
defimpl Zoi.TypeSpec do
def spec(schema, opts) do
Zoi.type_spec(schema.to, opts)
end
end
defimpl Inspect do
def inspect(type, opts) do
extra_fields = [
from: Inspect.inspect(type.from, opts),
to: Inspect.inspect(type.to, opts)
]
Zoi.Inspect.build(type, opts, extra_fields)
end
end
defimpl Zoi.JSONSchema.Encoder do
def encode(schema) do
Zoi.JSONSchema.encode_schema(schema.from)
end
end
defimpl Zoi.Describe.Encoder do
def encode(%{to: to}) do
Zoi.Describe.Encoder.encode(to)
end
end
end