RpcElixir.Types (elixir_ts_rpc v0.0.1)

Copy Markdown View Source

Type system for RPC procedure input/output specs.

Three entry points: resolve/1 normalizes a shorthand spec into the internal IR map, validate/2 checks untrusted input against a spec, and serialize/2 prepares handler output for JSON encoding.

Atom keys in validated input

After a successful validate/2 call, object values are returned with atom keys (e.g. %{id: "abc"}), not string keys. Handler functions therefore receive atom-keyed maps and should pattern-match accordingly:

def get(%{id: id}, _ctx), do: ...   # correct
def get(%{"id" => id}, _ctx), do: ... # wrong — key will be missing

Summary

Types

Internal IR map used throughout the type system; always has a kind string key.

Functions

Converts a shorthand spec term (atom, tagged tuple, or map) to an internal_spec IR map.

Serializes a server-produced value against spec into a JSON-encodable shape.

Validates user-supplied value against spec, returning {:ok, coerced} or {:error, tree}.

Types

internal_spec()

@type internal_spec() :: %{optional(atom()) => term(), kind: String.t()}

Internal IR map used throughout the type system; always has a kind string key.

Functions

resolve(already_resolved)

@spec resolve(
  :string
  | :integer
  | :float
  | :boolean
  | {:optional, term()}
  | {:nullable, term()}
  | {:list, term()}
  | {:stream, term()}
  | internal_spec()
  | map()
) :: internal_spec()

Converts a shorthand spec term (atom, tagged tuple, or map) to an internal_spec IR map.

serialize(spec, value)

@spec serialize(term(), term()) :: term()

Serializes a server-produced value against spec into a JSON-encodable shape.

spec may be a shorthand spec term (atom, tagged tuple, or map — see resolve/1) or an already-resolved IR map. Assumes value already conforms to spec (e.g. fresh from a handler) and raises on contract violations such as missing required fields — these indicate programmer error, not bad input.

validate(spec, value)

@spec validate(term(), term()) :: {:ok, term()} | {:error, map()}

Validates user-supplied value against spec, returning {:ok, coerced} or {:error, tree}.

spec may be a shorthand spec term (atom, tagged tuple, or map — see resolve/1) or an already-resolved IR map. Intended for untrusted input (decoded JSON), so contract violations come back as error trees rather than raises.

Object values in the returned {:ok, coerced} tuple always have atom keys; see the module doc for details.