Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit61a33237e0

README.md

opts

The contract an options table is held to. A call that reads a fixed set of keys acts on those keys and no others, so a key it does not know names a change the caller asked for and never got — a cube asked for size = 3 that comes back one unit wide, reporting success. Opts.check makes that a refusal carrying what to write instead: the key, the accepted set, and the nearest accepted spelling.

The same three parts answer for a name of any kind — tools.use names the near-miss toolbox, MaterialAuthor names the near-miss shader property — so the distance search lives here too, and every caller ranks candidates the same way.

Pure Luau, no engine dependencies.

Exports

  • Opts.check(where: string, value: any, accepted: { string }, inTable?: string) — raise unless every key of value is named by accepted. nil accepts.
  • Opts.forward(where: string, own: { string }, fn, ...) -> ... — call fn(...), and when it refuses an option, append the vocabulary where itself takes.
  • Opts.unknown(value, accepted) -> { string } — the keys value carries that accepted does not name, sorted.
  • Opts.nearest(key: string, candidates: { string }) -> string? — the candidate key is most plausibly a misspelling of, or nil.
  • Opts.editDistance(a: string, b: string, limit: number) -> number — single-character edits between two names, capped at limit + 1.

Usage

local Opts = require("@builtin::modules.opts")

-- The keys this call reads, named once.
local CUBE_OPTS = { "animate", "scale" }

function M.cube(name, x, y, z, opts)
    Opts.check("primitives.cube", opts, CUBE_OPTS)
    -- primitives.cube: unknown option 'scail'. Accepted: animate, scale. Did you mean 'scale'?

    -- The spawn target is handed to `entity.spawn`, so it is that call's
    -- contract a key is checked against — `own` says what this one takes.
    local e = Opts.forward("primitives.cube", { "opts.scale", "opts.animate" }, entity.spawn, name)
    -- entity.spawn: unknown option 'size'. Valid options: name, hidden, …
    --   (primitives.cube itself takes: opts.scale, opts.animate)
end

A call taking more than one table names which one the key was written in:

Opts.check("primitives.ground", color, { "r", "g", "b", "a" }, "color")
-- primitives.ground: unknown option 'red' in color. Accepted: r, g, b, a. Did you mean 'r'?

Notes

  • Refusals raise at level 0: the message is the whole error, so a caller reads the contract rather than the line inside the library that checked it.
  • A key of any type is reported by how it is written, so the positional form of a named shape ({ 200, 50, 50 } for { r = , g = , b = }) names its indices rather than passing as a table with nothing the call reads.
  • nearest is case-insensitive, and a candidate containing the key scores by how much longer it is, so roughnes prefers roughness over clearcoat_roughness. How far a plain misspelling may stray scales with the key's own length — a four-letter key admits two edits, a longer one three — so a short key is not answered with an unrelated short name.
  • Equal scores go to the shorter candidate, then the alphabetically earlier one, so the answer never depends on the order candidates were listed in.
  • forward matches the phrase both this module and the engine's own option checks use for the condition (unknown option '<key>'). Every other error passes through as raised.