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/struct.ex
defmodule Zoi.Struct do
@moduledoc """
A helper module to define and validate structs using Zoi schemas.
This module provides functions to extract `@enforce_keys` and struct fields from a Zoi struct schema.
It is particularly useful when you want to create Elixir structs that align with Zoi schemas.
## Examples
defmodule MyApp.SomeModule do
@schema Zoi.struct(__MODULE__, %{
name: Zoi.string() |> Zoi.nullable(),
age: Zoi.integer() |> Zoi.default(0) |> Zoi.optional(),
email: Zoi.string()
})
@type t :: unquote(Zoi.type_spec(@schema))
@enforce_keys Zoi.Struct.enforce_keys(@schema) # [:name, :email]
defstruct Zoi.Struct.struct_fields(@schema) # [:name, :email, {:age, 0}]
end
As shown in the example above, you can define a Zoi schema which will be used to generate a struct definition and especification.
By default, `Zoi.struct/3` makes all fields required unless they are marked as optional, and you can leverage the schema definition to
automatically generate the struct fields, type and enforce keys.
The example above is the same as the following definition:
defmodule MyApp.SomeModule do
@type t :: %MyApp.SomeModule{
name: binary() | nil,
age: integer(),
email: binary()
}
@enforce_keys [:name, :email]
defstruct [:name, :email, age: 0]
end
The advantage of using `Zoi.struct/3` is that you can leverage Zoi's schema capabilities to define complex types, default values, validations, etc, and have those reflected in your Elixir struct definitions automatically.
"""
alias Zoi.Types.Meta
@doc """
Returns a list of keys that are required for the struct based on the schema.
This is useful for defining `@enforce_keys` in Elixir structs.
"""
def enforce_keys(%Zoi.Types.Struct{fields: fields}) do
Enum.reduce(fields, [], fn {key, type}, acc ->
type =
case type do
%Zoi.Types.Default{inner: inner} -> inner
type -> type
end
if Meta.required?(type.meta) do
[key | acc]
else
acc
end
end)
end
@doc """
Returns a list of fields for the struct, where fields with default values are represented as tuples
of the form `{key, default_value}`.
This is useful for defining the fields of an Elixir struct.
"""
def struct_fields(%Zoi.Types.Struct{fields: fields}) do
Enum.map(fields, fn
{key, %Zoi.Types.Default{value: value}} -> {key, value}
{key, _type} -> key
end)
|> Enum.sort_by(fn
{_, _} -> 1
_ -> 0
end)
end
end