The nested struct with helpers to easily describe it and produce validation, coercion, and generation helpers.
Summary
Functions
DSL helper to produce coerce callbacks. The syntax is kinda weird,
but bear with it, please.
Declares the shape of the target nested map from a JSON Schema definition.
Declares the shape of the target nested map. the values might be
DSL helper to produce validate callbacks. The syntax is kinda weird,
but bear with it, please.
Functions
DSL helper to produce coerce callbacks. The syntax is kinda weird,
but bear with it, please.
It’s known to produce warnings in credo, I’m working on it.
coerce do
def data.age(age) when is_float(age), do: {:ok, age}
def data.age(age) when is_integer(age), do: {:ok, 1.0 * age}
def data.age(age) when is_binary(age), do: {:ok, String.to_float(age)}
def data.age(age), do: {:error, "Could not cast #{inspect(age)} to float"}
end
Declares the shape of the target nested map from a JSON Schema definition.
Accepts either a decoded JSON Schema map (with string keys) or a raw JSON
binary string. The schema is converted to an Estructura.Nested shape at
compile time using Estructura.Nested.JsonSchema.to_shape/1.
Any "default" values found in the schema are automatically used as
initial values (equivalent to calling init/1).
See Estructura.Nested.JsonSchema for the full type mapping reference.
Example
defmodule MyApi.Response do
use Estructura.Nested
json_schema %{
"type" => "object",
"properties" => %{
"id" => %{"type" => "integer"},
"name" => %{"type" => "string", "default" => "anonymous"},
"address" => %{
"type" => "object",
"properties" => %{
"city" => %{"type" => "string"},
"zip" => %{"type" => "string"}
}
},
"tags" => %{"type" => "array", "items" => %{"type" => "string"}},
"status" => %{"type" => "string", "enum" => ["active", "inactive"]}
},
"required" => ["id", "name"]
}
endYou can also load from a file:
json_schema File.read!("priv/schemas/response.json")
Declares the shape of the target nested map. the values might be:
:string|:integeror another simpletypeunderstood byStreamData[type]to declare a list of elements of a singletypemapto declare a nesting level; in such a case, the module with the FQN is created, carrying the struct of the same behaviourmfatuple pointing out to the generator for this value
Example
defmodule User do
use Estructura.Nested
shape %{
name: :string,
address: %{city: :string, street: %{name: [:string], house: :string}},
data: %{age: :float}
}
end
%User{}would result in
%User{
address: %User.Address{
city: nil,
street: %User.Address.Street{house: nil, name: []}
},
data: %User.Data{age: nil},
name: nil
}
DSL helper to produce validate callbacks. The syntax is kinda weird,
but bear with it, please.
It’s known to produce warnings in credo, I’m working on it.
validate do
def address.street.postal_code(<<?0, code::binary-size(4)>>),
do: {:ok, code}
def address.street.postal_code(code),
do: {:error, "Not a postal code (#{inspect(code)})"}
end