Dextrin.Schema.Compiler (Dextrin v0.1.0)

Copy Markdown View Source

Compiles a parsed .dxns document (an ordinary decoded DXN value — a .dxns file is valid .dxn, no new grammar; what makes it a schema document is purely the shape of the value it parses to: a map from name to type expression) into Dextrin.Schema.Compiled entries.

%schema{}/%field{} are recognized here directly, as Dextrin.Struct{name: "schema" | "field"} opaque shapes straight out of Dextrin.decode/1 — they're never looked up in a registry, the same way built-in tags are recognized by name in Dextrin.Text.Actions rather than registered. This sidesteps an obvious bootstrapping question (doesn't parsing a .dxns file need a schema for its own schema/field structs?) the same way JSON Schema's own vocabulary is fixed tooling knowledge rather than itself validated against a schema.

An entry whose value isn't a %schema{} is a named type instead: a reusable name for some combination of the fixed type_expr vocabulary, e.g. PositiveInt: {:refine :integer {min: 1}} — the same move Clojure's Malli makes with [:map [:x :int]]-style plain data instead of a bespoke schema DSL. Purely data — no Elixir code, no registry callback — so any conformant reader in any language can resolve it the same way it already resolves refine/list-of/etc.

Summary

Functions

Compiles every entry of a decoded .dxns document into base_registry — a struct schema for each %schema{} entry, a named type_expr for every other entry. predicates resolves refine-fn: names — a plain map, not the struct registry itself, since a refine-fn is a validity check, not a decoder.

Functions

compile(schema_doc, base_registry, predicates \\ %{})

@spec compile(term(), Dextrin.Registry.t(), %{
  optional(String.t()) => Dextrin.Schema.Compiled.refine_fn()
}) :: {:ok, Dextrin.Registry.t()} | {:error, term()}

Compiles every entry of a decoded .dxns document into base_registry — a struct schema for each %schema{} entry, a named type_expr for every other entry. predicates resolves refine-fn: names — a plain map, not the struct registry itself, since a refine-fn is a validity check, not a decoder.

Named types defined in this document may reference any type already known to base_registry (from an earlier compile/3 call), but not one declared alongside them in the same document — .dxns's own map type has no ordering guarantee to resolve forward references against, and no real usage yet justifies the dependency-resolution machinery a same-document case would need. A schema's fields, compiled afterwards, can freely use any named type from either source.