# `Monty.Config.Resolvers`
[🔗](https://github.com/d-led/ex.tbp.monty/blob/v0.1.0/packages/ex_tbp_monty_core/lib/monty/config/resolvers.ex#L1)

Resolves the OmegaConf interpolations Monty's configs are written in.

Composition leaves `${...}` strings exactly as Monty's snapshots have them;
this module turns them into values:

    ${constants.min_eval_steps}                     a reference into the tree
    ${oc.env:MONTY_DATA}                            an environment variable
    ${oc.env:MONTY_DATA,/tmp/data}                  ... with a default
    ${monty.class:tbp.monty.geometry.Rotation}      a class reference
    ${np.array:[2, 0.5, 0.5]}                       a numeric array
    ${np.ones:3}                                    [1.0, 1.0, 1.0]
    ${np.list_eval:[np.pi / 8, np.pi * 2]}          arithmetic
    ${path.expanduser:~/tbp/data}                   ~ expanded
    ${path.tests:fixtures/cube.json}                inside Monty's tests/

`monty.class` deserves a note: Monty returns the *class object*, which an
Elixir process cannot hold. This returns the dotted path as a string and
leaves the mapping to an Elixir module to `Monty.Config.Registry`, so the
config file stays readable and an unknown class stays visible instead of
blowing up during composition.

# `opts`

```elixir
@type opts() :: [env: (String.t() -&gt; String.t() | nil), monty_root: Path.t()]
```

# `resolve`

```elixir
@spec resolve(map(), opts()) :: {:ok, map()} | {:error, term()}
```

Resolves every interpolation in a composed config.

Runs to a fixed point, because a value may reference one that is itself an
interpolation. A tree that still contains `${` after that is reported as
unresolved — never silently passed through as a string.

# `unresolved?`

```elixir
@spec unresolved?(term()) :: boolean()
```

True when any string in the tree still contains an interpolation.

---

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