# `Macaw.Layers.Use`
[🔗](https://github.com/dcoai/macaw_layers/blob/v0.2.2/lib/macaw/layers/use.ex#L1)

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: %{}}}}

# `path`

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

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

# `t`

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

# `bind`

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

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

# `mask`

```elixir
@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`

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

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

# `new`

```elixir
@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`

```elixir
@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`

```elixir
@spec resolve(module(), t(), (term() -&gt; {: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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
