Dextrin.Schema.Tree (Dextrin v0.3.2)

Copy Markdown View Source

A tree of .dxns files read as one (Jan, 2026-10-20): every entry named from where its file lies (DXNS.md §6, Dextrin.Schema.Layout), the files compiled in the order their references need -- so a reference to another file's named type resolves whatever order the files sort in -- and every problem reported with its file and line:

  • a file that is not DXN, or not a map of names to definitions;
  • a definition that does not compile;
  • a versioned file holding another version, and one version of a name held by two files;
  • files that need each other (a cycle across files is not resolved yet);
  • a name that resolves to nothing -- a typo such as acme.comon/Money -- unless its namespace is declared extern:, supplied by another tree or a provider.

mix dextrin.check is this, for CI.

Summary

Types

One problem: the file (relative to its root), the line, and what is wrong.

What a tree that is in order holds.

Functions

Every .dxns file under roots (files or directories, searched recursively), compiled into one registry over opts[:registry]: {:ok, registry, summary}, or {:error, problems} with every problem found, in file and line order. extern: lists namespaces whose names are known to be supplied elsewhere.

The named types roots define, compiled as load/2 compiles them but past any problem -- what a file of the tree needs from the others when it is compiled on its own (Dextrin.Schema.FileResolver). Struct schemas are left out: each is loaded where it is asked for.

Types

problem()

@type problem() :: %{file: String.t(), line: pos_integer(), message: String.t()}

One problem: the file (relative to its root), the line, and what is wrong.

summary()

@type summary() :: %{files: non_neg_integer(), definitions: non_neg_integer()}

What a tree that is in order holds.

Functions

load(roots, opts \\ [])

@spec load([Path.t()], keyword()) ::
  {:ok, Dextrin.Registry.t(), summary()} | {:error, [problem()]}

Every .dxns file under roots (files or directories, searched recursively), compiled into one registry over opts[:registry]: {:ok, registry, summary}, or {:error, problems} with every problem found, in file and line order. extern: lists namespaces whose names are known to be supplied elsewhere.

named_types(roots)

@spec named_types([Path.t()]) :: %{required(String.t()) => term()}

The named types roots define, compiled as load/2 compiles them but past any problem -- what a file of the tree needs from the others when it is compiled on its own (Dextrin.Schema.FileResolver). Struct schemas are left out: each is loaded where it is asked for.