Lmml.Settings (lmml v0.2.0)

View Source

Optional project settings carried by a Lmml.Bundle.

Settings are not a distinct mechanism -- they are simply an embed literally named "settings.yaml" (or "settings.json"), exactly like any other embed: @@@settings.yaml ... @@@ inline, or @settings.yaml referencing a zip entry inside a .lmmlz. This module looks that embed up, decodes it, and exposes its top-level fields as a plain map -- mirroring Lmml.Manifest's API shape.

A bundle mentioning no settings embed at all has no settings -- that is a normal, fully-supported, non-error state (load/1 returns {:ok, nil}), not something to special-case at every call site.

Encoding support

Which decoder is used depends on the settings embed's file extension:

  • .json -- decoded with OTP's built-in :json (this project has no Jason dependency).

  • .yaml / .yml -- decoded with a small, hand-rolled YAML-subset decoder (this project also has no YAML dependency). Support is deliberately limited to the common flat and lightly-nested shapes:

    • key: value mapping lines, where value is an integer, float, true/false, null, or a bare or quoted string;
    • nested maps written with indentation (key: followed by indented child: value lines); and
    • blank lines and full-line # comments.

    Anything outside that subset -- sequences/lists (- item), multi-line |/> block scalars, anchors/aliases, tags, etc. -- is rejected with {:error, {:unsupported_yaml, line, reason}} rather than silently mis-decoded. If a settings narrative needs richer YAML, name the embed settings.json instead.

Summary

Functions

Fetches a top-level key from the settings' decoded data as {:ok, term}, or :error if absent.

Fetches a top-level key from the settings' decoded data, or nil if absent.

Loads and decodes bundle's settings embed, if any.

Same as load/2, but raises on failure. A settings-less bundle still returns nil, not an exception.

The reserved embed name a bundle's settings are looked up by by default.

Types

t()

@type t() :: %Lmml.Settings{data: map()}

Functions

fetch(settings, key)

@spec fetch(t(), String.t()) :: {:ok, term()} | :error

Fetches a top-level key from the settings' decoded data as {:ok, term}, or :error if absent.

get(settings, key)

@spec get(t(), String.t()) :: term() | nil

Fetches a top-level key from the settings' decoded data, or nil if absent.

load(bundle, name \\ "settings.yaml")

@spec load(Lmml.Bundle.t(), String.t()) :: {:ok, t() | nil} | {:error, term()}

Loads and decodes bundle's settings embed, if any.

Returns:

  • {:ok, %Lmml.Settings{}} -- a settings embed exists and decodes to a mapping.
  • {:ok, nil} -- no settings embed with name is mentioned anywhere in the narrative. This is the common case for a settings-less bundle, not an error.
  • {:error, reason} -- a settings embed is mentioned, but either its content is unresolvable (e.g. an @settings.yaml reference in a bare .lmml, or a dangling reference into a .lmmlz's entries -- see Lmml.Bundle.embed/2), or its resolved content cannot be decoded ({:invalid_settings, reason}).

load!(bundle, name \\ "settings.yaml")

@spec load!(Lmml.Bundle.t(), String.t()) :: t() | nil

Same as load/2, but raises on failure. A settings-less bundle still returns nil, not an exception.

name()

@spec name() :: String.t()

The reserved embed name a bundle's settings are looked up by by default.