Estructura.Nested.JsonSchema (estructura v1.12.0)

Copy Markdown View Source

Converts JSON Schema definitions into Estructura.Nested-compatible shape maps.

This module provides a bridge between the standard JSON Schema format and Estructura.Nested, allowing you to define nested structures from JSON Schema documents instead of (or in addition to) the manual shape/1 DSL.

Usage

The primary entry point is to_shape/1, which accepts either a decoded JSON Schema map or a raw JSON string:

iex> schema = %{
...>   "type" => "object",
...>   "properties" => %{
...>     "name" => %{"type" => "string"},
...>     "age" => %{"type" => "integer"}
...>   }
...> }
iex> {shape, init, _meta} = Estructura.Nested.JsonSchema.to_shape(schema)
iex> shape
%{name: :string, age: :integer}
iex> init
%{}

Or use it directly in a module definition via the json_schema/1 macro provided by Estructura.Nested:

defmodule MyStruct do
  use Estructura.Nested
  json_schema %{
    "type" => "object",
    "properties" => %{
      "name" => %{"type" => "string"},
      "tags" => %{"type" => "array", "items" => %{"type" => "string"}}
    }
  }
end

Type Mapping

JSON Schema types and formats are mapped to Estructura types as follows:

  • "string" -> :string
  • "string" + "date-time" -> :datetime
  • "string" + "date" -> :date
  • "string" + "time" -> :time
  • "string" + "uri" -> Estructura.Nested.Type.URI
  • "string" + "uuid" -> Estructura.Nested.Type.UUID
  • "string" + "ipv4" / "ipv6" -> Estructura.Nested.Type.IP
  • "string" + "email" -> {:string, kind_of_codepoints: :ascii}
  • "integer" -> :integer (or :positive_integer when minimum >= 1)
  • "number" -> :float
  • "boolean" -> :boolean
  • "object" -> nested %{...} map (recurse)
  • "array" -> [:type] or [%{...}]
  • "enum" -> {Estructura.Nested.Type.Enum, values}
  • "null" -> {:constant, nil}

Features

  • $ref resolution (local JSON Pointer references)
  • allOf merging
  • oneOf / anyOf -> :mixed types
  • default values -> init map
  • Nullable types (["string", "null"])

Summary

Functions

Converts a JSON Schema into a tuple of {shape, init, metadata} suitable for Estructura.Nested.

Same as to_shape/1 but raises on errors.

Types

init()

@type init() :: %{optional(atom()) => term()}

metadata()

@type metadata() :: %{
  optional(:required) => [atom()],
  optional(:title) => binary(),
  optional(:description) => binary()
}

shape()

@type shape() :: %{required(atom()) => term()}

Functions

to_shape(schema)

@spec to_shape(map() | binary()) :: {shape(), init(), metadata()} | {:error, term()}

Converts a JSON Schema into a tuple of {shape, init, metadata} suitable for Estructura.Nested.

Accepts either a decoded map or a raw JSON binary string.

Examples

iex> schema = %{
...>   "type" => "object",
...>   "properties" => %{
...>     "name" => %{"type" => "string", "default" => "anonymous"},
...>     "score" => %{"type" => "number"}
...>   },
...>   "required" => ["name"]
...> }
iex> {shape, init, meta} = Estructura.Nested.JsonSchema.to_shape(schema)
iex> shape
%{name: :string, score: :float}
iex> init
%{name: "anonymous"}
iex> meta
%{required: [:name]}

to_shape!(schema)

@spec to_shape!(map() | binary()) :: {shape(), init(), metadata()} | no_return()

Same as to_shape/1 but raises on errors.