Macaw.Layers.Use (macaw_layers v0.2.2)

Copy Markdown View Source

A use site (spec/02 §7): a fragment used at a position, resolved ref → local → mask → bind → stack.

%Macaw.Layers.Use{
  id:     {:use, 7},          # the site's own identity, the same site wherever it sits
  ref:    {:style, 11},       # which fragment: an id, a local key, or nil
  mask:   [["stroke"]],       # paths removed here, so a lower layer shows through; or :all
  vars:   %{"color" => …},    # what the fragment's variables mean here
  local:  %{opacity: 0.8},    # what is added or overridden here
  key:    "series",           # the name a name-keyed kind is declared under, here
  origin: nil                 # the entry an unlocked site was copied from
}

The site is a struct, so it is a leaf of every walk but the two id walks (Macaw.Layers.Fragment.refs/2, relocate/3), which read its parts by name. Mask and bind run after local, so both speak for everything the site contributes; a mask of :all removes the whole site, its local included. A reference the fetch cannot find is transparent: the site is its local alone, and the miss is reported.

Ported from visualize's Visualize.Chart.Use.

iex> alias Macaw.Layers.Use
iex> Use.new({:style, 2}, [Use.new({:style, 1})]).id
{:use, 2}
iex> Use.mask(%{frames: %{"main" => %{legend: %{}, margin: %{}}}}, [[:frames, "main", :margin]])
%{frames: %{"main" => %{legend: %{}}}}

Summary

Types

A path into a fragment: its keys from the root, or a bare name for one key.

t()

Functions

Macaw.Layers.Var.bind/2: the fragment's variables substituted.

The fragment with each path removed (spec/02 §4): a path is the keys from the root, read by spelling, or a bare name for one key; a node it empties is kept as an empty map; a path that names nothing removes nothing; :all removes everything.

A use of ref with id {:use, 1} and the empty parts.

A use of ref with a fresh id, one more than the highest among siblings, the ids of an inline composite's sites among them, so ids are unique across a whole tree.

The site over a body already in hand: its local cascaded over the body, its mask over the result, its variables bound over all of it — everything resolve/3 does after the fetch. A mask of :all is the whole site removed.

One site through fetch, a function from an id to {:ok, fragment} or :error: {:ok, contribution}, or {:missing, ref, contribution} where the ref was not found, the contribution then the local alone, masked and bound. A nil ref is an inline site.

Types

path()

@type path() :: [term()] | atom() | String.t()

A path into a fragment: its keys from the root, or a bare name for one key.

t()

@type t() :: %Macaw.Layers.Use{
  id: {:use, pos_integer()},
  key: String.t() | nil,
  local: map(),
  mask: [path()] | :all,
  origin: term(),
  ref: term(),
  vars: map()
}

Functions

bind(fragment, vars)

@spec bind(term(), map()) :: term()

Macaw.Layers.Var.bind/2: the fragment's variables substituted.

mask(fragment, paths)

@spec mask(map(), [path()] | :all) :: map()

The fragment with each path removed (spec/02 §4): a path is the keys from the root, read by spelling, or a bare name for one key; a node it empties is kept as an empty map; a path that names nothing removes nothing; :all removes everything.

new(ref)

@spec new(term()) :: t()

A use of ref with id {:use, 1} and the empty parts.

new(ref, siblings)

@spec new(term(), [t()]) :: t()

A use of ref with a fresh id, one more than the highest among siblings, the ids of an inline composite's sites among them, so ids are unique across a whole tree.

over(type, use, body)

@spec over(module(), t(), map()) :: map()

The site over a body already in hand: its local cascaded over the body, its mask over the result, its variables bound over all of it — everything resolve/3 does after the fetch. A mask of :all is the whole site removed.

resolve(type, use, fetch)

@spec resolve(module(), t(), (term() -> {:ok, map()} | :error)) ::
  {:ok, map()} | {:missing, term(), map()}

One site through fetch, a function from an id to {:ok, fragment} or :error: {:ok, contribution}, or {:missing, ref, contribution} where the ref was not found, the contribution then the local alone, masked and bound. A nil ref is an inline site.