Squirrelix.TypeMapper (Squirrelix v0.4.0)

Copy Markdown View Source

Maps Postgres type names into Squirrelix's Elixir type metadata and typespecs.

Postgres enums

Custom Postgres enums (kind: "e") map to the internal atom :string and emit String.t() in generated @specs. Runtime encode/decode passes enum labels through as plain strings — Squirrelix does not generate Gleam-style enum ADTs.

JSON and JSONB

JSON columns map to the internal atom :map (shared by json and jsonb) but emit term() in generated @specs. JSON values are not always objects, and Postgrex may return maps, lists, or primitives depending on the stored payload. term() matches Elixir 1.20 practice for dynamically typed JSON columns; row result maps still use map() with required/1 keys via row_typespec/1.

Composite types

Postgres composite types (kind: "c", including create type ... as (...)) are intentionally unsupported. Squirrelix rejects them with an UnsupportedPostgresType error and an actionable hint (select individual fields, or cast to json/jsonb/text). This matches Gleam Squirrel and keeps generated Elixir APIs limited to stdlib typespecs and flat row maps — no nested composite modules or opaque encodings.

Unsupported types

Postgres range/multirange types and several other built-ins are intentionally unsupported. Inference returns UnsupportedPostgresType with an actionable hint (for example: select bounds as separate columns, or cast to text / jsonb in SQL). See the Types guide for the full inventory.

Summary

Types

elixir_type()

@type elixir_type() :: atom() | {:list, elixir_type()}

Functions

column_typespec(name, type, nullable?)

@spec column_typespec(atom(), elixir_type(), boolean()) :: String.t()

from_postgres(name, opts \\ [])

@spec from_postgres(
  String.t(),
  keyword()
) ::
  {:ok, elixir_type()} | {:error, Squirrelix.Error.UnsupportedPostgresType.t()}

hint_for(name)

@spec hint_for(String.t()) :: String.t() | nil

hint_for(name, kind)

@spec hint_for(String.t(), String.t() | nil) :: String.t() | nil

normalize_type(type)

@spec normalize_type(term()) ::
  {:ok, elixir_type()} | {:error, Squirrelix.Error.UnsupportedPostgresType.t()}

return_typespec(columns)

@spec return_typespec([] | [{atom(), elixir_type(), boolean()}]) :: String.t()

row_typespec(columns)

@spec row_typespec([{atom(), elixir_type(), boolean()}]) :: String.t()

typespec(arg1)

@spec typespec(elixir_type()) :: String.t()

validate_enum(name, list)

@spec validate_enum(String.t(), [String.t()]) :: :ok | {:error, :no_variants}