AshLua.Encoder (ash_lua v0.1.0)

Copy Markdown View Source

Conversions between Elixir/Ash values and the plain shapes that :luerl (via the :lua package) can encode as Lua tables.

Lua doesn't have atoms or sigils — atoms are rendered as strings, Decimal/Date/DateTime/ NaiveDateTime/Time as their canonical string forms, and structs as plain attribute maps (no relationships, no calculations, no aggregates unless they happen to be already loaded as a field value).

Summary

Functions

Decodes a Lua-side input value into the shape Ash actions expect for params/arguments.

Encodes an Ash error tree into a Lua-friendly table.

Encodes an Ash action result to a Lua-friendly value (plain Elixir maps/lists/primitives that Lua.encode!/2 knows how to convert).

Encodes a result against a template produced by AshLua.Fields.for_action/4.

Functions

decode_input(value)

@spec decode_input(term()) :: term()

Decodes a Lua-side input value into the shape Ash actions expect for params/arguments.

Luerl decodes Lua tables as a list of two-tuples — keyed by integers for sequences and by strings for maps. We normalize:

  • integer-keyed (sequence) tables → plain lists, sorted by index
  • string-keyed tables → maps with string keys (Ash accepts string-keyed params)
  • empty tables → empty maps (Ash actions are always invoked with a map of params)

Recurses into values.

encode_error(error)

@spec encode_error(term()) :: map()

Encodes an Ash error tree into a Lua-friendly table.

Walks Ash.Error.Invalid/Ash.Error.Forbidden classes to their leaves, then dispatches each leaf through the AshLua.Error protocol. Leaves without a protocol impl render as an opaque "unknown error" entry with a uuid that's logged via Logger.warning/1 so operators can correlate the surfaced uuid with full stacktrace details.

The envelope carries a class tag ("invalid" | "forbidden" | "framework" | "unknown") and the full per-error list in errors. Consumers that want a one-line summary should pick the appropriate entry from errors themselves rather than read a top-level message — joining or first-pick'ing here would silently mislead in the multi-error case.

encode_result(value)

@spec encode_result(term()) :: term()

Encodes an Ash action result to a Lua-friendly value (plain Elixir maps/lists/primitives that Lua.encode!/2 knows how to convert).

encode_with_template(value, template)

@spec encode_with_template(term(), term()) :: term()

Encodes a result against a template produced by AshLua.Fields.for_action/4.

Walks the template recursively, pulling only the requested fields from records, typed maps, tuples, and union values. :passthrough template nodes fall back to the unconstrained encode_result/1 path.