asset.create opts validator — PURE module (no FFI, no VFS).
Checks a creation `opts` table against the schema produced by
`asset.createSchema(typeName)` (the Rust FFI that parses the `opts`
type annotation off a type's `behavior.luau` onCreate hook). Schema
in, validated opts (or a teaching error string) out. Consumed by
`asset.create` (../init.luau), which calls `M.validate` before
forwarding opts to the type's onCreate.
Schema shape (see crates/zero_scripting asset bindings):
{ kind = "schema"|"legacy"|"none"|"error",
desc?, example?, open?, error?,
params = { { name, shape, optional, default?, desc } },
indexer = <shape>? }
where <shape> is the recursive encoding
{ kind = "string"|"number"|"boolean"|"buffer"|"any"|"literals"|"array"
|"union"|"table",
literals?, item?, members?, fields?, indexer? }
Errors are TEACHING errors: they state what was wrong at which path
(`opts.cfg.size`), what was expected, and then render the full
creation-parameter contract so the caller can fix the call without
hunting down the type's behavior.luau.
shapeName(shape: ValidatorShape?) → string
Human-readable name for a shape: literals render as the quoted
union, arrays as `{ T }`, tables as `table`, everything else as its
kind. Nil / malformed shapes degrade to `any`.
Sibling renderer: `render_schema_ty` in crates/zero_lsp/src/create_schema.rs
renders the same shapes as Luau TYPE TEXT for the LSP overload signature —
keep the two presentations in step when changing either.
| arg | type | description |
|---|
| shape | ValidatorShape? | |
shapeName(shape: ValidatorShape?) → string
Render a single parameter shape the same way the contract
rendering does — literal unions as the quoted alternation
(`"png" | "jpg"`), arrays as `{ T }`, tables as `table`, primitives
as their kind, nil/malformed as `any`. Used by `asset.describe` for
each param's `type` field so the data view matches the printed
contract.
| arg | type | description |
|---|
| shape | ValidatorShape? | The shape table off a schema param (nil allowed). |
examples
V.shapeName({ kind = "literals", literals = { "png" } })valueRepr(value: any) → string
Short, safe repr of a runtime value for error messages.
| arg | type | description |
|---|
| value | any | |
renderContract(schema: ValidatorSchema) → string
Render a schema's creation-parameter contract as one aligned
line per parameter — `name : type (required)` for required params,
`name : type = <default>` for defaulted ones, `name : type?` for
plain optionals — each suffixed with `— desc` when the param has a
description. An open schema's indexer renders last as an
`[extra keys] : type` line. Pure string building; safe to call on
any schema kind (non-`schema` kinds render an empty contract).
| arg | type | description |
|---|
| schema | ValidatorSchema | The schema table from `asset.createSchema`. |
examples
print(V.renderContract(schema))
unescapeString(inner: string) → string
Unescape the simple escapes a Luau string literal can carry. The
text already passed Rust-side validation, so this only needs the
common cases — not a full lexer.
| arg | type | description |
|---|
| inner | string | |
parseDefault(text: any) → void
Parse a default-value literal (the verbatim text from the type
annotation, e.g. `"png"`, `true`, `0.5`, `{ 1, 2 }`) into a runtime
value. Returns (value, true) on success, (nil, false) when the text
can't be interpreted — the caller then simply leaves the key unset
rather than guessing.
| arg | type | description |
|---|
| text | any | |
editDistance(a: string, b: string) → number
Classic Levenshtein distance, case-insensitive (both sides lowered
by the caller). Small inputs only (param names), so the O(n*m) DP is
fine. `#`/string.sub are byte-based — safe because the compared
strings are Luau identifiers (param names), which are ASCII-only.
| arg | type | description |
|---|
| a | string | |
| b | string | |
suggestName(key: string, params: { ValidatorParam }) → string
Closest declared param name within edit distance 2 of `key`
(case-insensitive), or nil when nothing is close enough.
| arg | type | description |
|---|
| key | string | |
| params | { ValidatorParam } | |
checkValue(shape: ValidatorShape?, value: any, path: string) → void
Check `value` against `shape`; returns an error string (with `path`
locating the offending value) or nil when the value conforms.
| arg | type | description |
|---|
| shape | ValidatorShape? | |
| value | any | |
| path | string | |
validate(schema: ValidatorSchema, opts: { [string]: any }?) →
Validate (and default-fill) a creation `opts` table against an
`asset.createSchema` result. Returns `(validatedOpts, nil)` on
success — always a NEW table for `schema`-kind schemas (declared
params + admitted extras; the input is never mutated) — or
`(nil, err)` where `err` is a BARE teaching error string: the
violation, its path, and the full rendered parameter contract.
The caller owns presentation — no "asset.create: " prefix is added
here. The caller prepends its own call-site context before raising.
| arg | type | description |
|---|
| schema | ValidatorSchema | The schema from `asset.createSchema(typeName)`. |
| opts | { [string]: any }? | The caller-supplied opts table (nil allowed). |
examples
local out, err = V.validate(schema, { bytes = png })withContract(err: string) → string
| arg | type | description |
|---|
| err | string | |