Macaw.Layers.Composite (macaw_layers v0.2.2)

Copy Markdown View Source

Composites (spec/02 §8): a fragment whose content is a list of use sites and its own variable declarations, stored as structure and flattened at deployment.

%{composite: %{uses: [%Use{…}, …], vars: %{"color_1" => %{default: …}}}}

flatten/3 resolves every site recursively — ref → local → mask → bind — through a fetch, places each by its kind through the type's place/3, and stacks the placed layers: a whole document with no ids and no uses. Composites nest; one that reaches itself is refused at the site that closed the loop. A reference the store no longer holds shows through and is reported.

Ported from visualize's Visualize.Chart.Composite and Refs, the placement and the inlining of ids made the type's.

Summary

Types

What flatten/3 reports: every reference that showed through, {id, at}, at the use id of the site that named it or the path of a reference inside the document, and every name-keyed site with no key, by its use id.

Functions

Whether a fragment is one key, composite, holding uses.

A whole document as a composite of inline sites, one kind each, through the type's decompose/1 (spec/02 §8.2): flattening it is the document again.

A composite flattened through fetch (spec/02 §8.1): {:ok, document, report}, or {:error, {:cycle, chain}}, chain the ids from the outer composite to the repeated one. A fragment that is not a composite flattens to itself. Once the sites are placed, the ids left at reference sites inside the document are resolved by the type's inline/2, where it has one.

One site's contribution as the layer that declares it where a whole document keeps its kind (spec/02 §8.2), through the type's place/3, or :keyless. A contribution of no kind (a whole document, an empty site) is its own layer.

Types

report()

@type report() :: %{
  missing: [{Macaw.Layers.Fragment.id(), term()}],
  keyless: [{:use, pos_integer()}]
}

What flatten/3 reports: every reference that showed through, {id, at}, at the use id of the site that named it or the path of a reference inside the document, and every name-keyed site with no key, by its use id.

Functions

composite?(fragment)

@spec composite?(term()) :: boolean()

Whether a fragment is one key, composite, holding uses.

decompose(type, document)

@spec decompose(module(), map()) :: map()

A whole document as a composite of inline sites, one kind each, through the type's decompose/1 (spec/02 §8.2): flattening it is the document again.

flatten(type, fragment, fetch)

@spec flatten(module(), map(), (Macaw.Layers.Fragment.id() -> {:ok, map()} | :error)) ::
  {:ok, map(), report()} | {:error, {:cycle, [Macaw.Layers.Fragment.id()]}}

A composite flattened through fetch (spec/02 §8.1): {:ok, document, report}, or {:error, {:cycle, chain}}, chain the ids from the outer composite to the repeated one. A fragment that is not a composite flattens to itself. Once the sites are placed, the ids left at reference sites inside the document are resolved by the type's inline/2, where it has one.

place(type, contribution, key)

@spec place(module(), map(), String.t() | nil) :: {:ok, map()} | :keyless

One site's contribution as the layer that declares it where a whole document keeps its kind (spec/02 §8.2), through the type's place/3, or :keyless. A contribution of no kind (a whole document, an empty site) is its own layer.