libero/walker
Types
A custom type discovered by the walker, grouping all its variants.
pub type DiscoveredType {
DiscoveredType(
module_path: String,
type_name: String,
type_params: List(String),
variants: List(DiscoveredVariant),
)
}
Constructors
-
DiscoveredType( module_path: String, type_name: String, type_params: List(String), variants: List(DiscoveredVariant), )
A single discovered variant, used in typed decoder codegen.
pub type DiscoveredVariant {
DiscoveredVariant(
module_path: String,
variant_name: String,
atom_name: String,
float_field_indices: List(Int),
field_labels: List(option.Option(String)),
fields: List(field_type.FieldType),
)
}
Constructors
-
DiscoveredVariant( module_path: String, variant_name: String, atom_name: String, float_field_indices: List(Int), field_labels: List(option.Option(String)), fields: List(field_type.FieldType), )Arguments
- module_path
-
Gleam module path, e.g. “shared/discount”.
- variant_name
-
PascalCase constructor name, e.g. “AdminData”.
- atom_name
-
snake_case atom name, e.g. “admin_data”.
- float_field_indices
-
0-based indices of fields whose Gleam type is Float. Used by the JS ETF encoder to distinguish Int from Float (JS erases this distinction at runtime).
- field_labels
-
Labels for each field.
Nonefor unlabelled,Some("label")for labelled. Carried alongsidefieldsfor JSON codegen; ignored by ETF codegen. - fields
-
Structured types of each field, in declaration order.
Values
pub fn qualified_atom_name(
module_path module_path: String,
variant_name variant_name: String,
) -> String
Build a module-qualified atom name from a module path and variant name. “shared/discount” + “Discount” → “shared_discount__discount”. Two modules with the same variant name produce distinct atoms, so the atom→decoder reverse mapping cannot collide.
pub fn to_snake_case(name: String) -> String
Convert a PascalCase variant name to snake_case for the wire atom.
“AdminData” → “admin_data”, “One” → “one”, “TwoOrMore” → “two_or_more”.
Handles consecutive uppercase: “XMLParser” → “xml_parser”.
Must stay aligned with snakeCase() in etf/wire_ffi.mjs.
pub fn walk(
seeds seeds: List(#(String, String)),
file_paths file_paths: List(String),
) -> Result(List(DiscoveredType), List(gen_error.GenError))
Walk the type graph starting from seeds, discovering all reachable custom types. Seeds come from scanner output (param/return types of endpoints). file_paths are the .gleam files to search for type definitions. BFS traversal order affects discovery order but not correctness: all reachable types are found regardless of queue order.