lode/type_
The Ecto type system, re-expressed without behaviours or parameterized types.
In Ecto a “type” is a module implementing cast/load/dump/equal? (plus the
Ecto.Type / Ecto.ParameterizedType behaviours). Gleam has no behaviours,
so a type is just a record of functions, parameterized by the Gleam type a
it produces. Composite types (array, map) are ordinary functions over
LodeType, and custom types (Enum, UUID) are ordinary constructors.
cast: external input (e.g. params) -> runtime valueaload: database value -> runtime valueadump: runtime valuea-> database valueequal: semantic equality (matters for Decimal, datetimes, …)
Types
A type-erased type that operates purely on Value. The schema and changeset
layers are generic over a row type and can’t hold a heterogeneous list of
LodeType(a) (each a differs per field), so they store this erased form.
cast: validate+normalize external input into a canonical, DB-readyValueload: validate+normalize a database value into a canonicalValue
Both produce a canonical Value (the result of casting then dumping), so the
changeset can work entirely in Value-space while still enforcing the type.
pub type FieldType {
FieldType(
name: String,
cast: fn(value.Value) -> Result(value.Value, Nil),
load: fn(value.Value) -> Result(value.Value, Nil),
)
}
Constructors
-
FieldType( name: String, cast: fn(value.Value) -> Result(value.Value, Nil), load: fn(value.Value) -> Result(value.Value, Nil), )
pub type LodeType(a) {
LodeType(
name: String,
cast: fn(value.Value) -> Result(a, Nil),
load: fn(value.Value) -> Result(a, Nil),
dump: fn(a) -> Result(value.Value, Nil),
equal: fn(a, a) -> Bool,
)
}
Constructors
-
LodeType( name: String, cast: fn(value.Value) -> Result(a, Nil), load: fn(value.Value) -> Result(a, Nil), dump: fn(a) -> Result(value.Value, Nil), equal: fn(a, a) -> Bool, )Arguments
- name
-
Stable name used in error messages and (later) for SQL type mapping.
Values
pub fn cast(
of t: LodeType(a),
value v: value.Value,
) -> Result(a, Nil)
Run the cast step.
pub fn dump(
of t: LodeType(a),
value v: a,
) -> Result(value.Value, Nil)
Run the dump step.
pub fn equal(of t: LodeType(a), left x: a, right y: a) -> Bool
Semantic equality for this type.
pub fn erase(t: LodeType(a)) -> FieldType
Erase a typed LodeType(a) into a Value-only FieldType by composing
cast/load with dump.
pub fn load(
of t: LodeType(a),
value v: value.Value,
) -> Result(a, Nil)
Run the load step.
pub fn simple(
name name: String,
decode decode: fn(value.Value) -> Result(a, Nil),
encode encode: fn(a) -> Result(value.Value, Nil),
) -> LodeType(a)
Build a type whose cast and load share the same conversion, with structural equality. This covers most primitive types.