libero/scanner
Scanning for handler-as-contract endpoints.
Walks the server source tree to discover handler functions whose
signatures define the wire contract: each public function with last
parameter HandlerContext, return type #(_, HandlerContext), and
all other types from shared/.
Types
A single handler endpoint discovered by scanning function signatures. Each represents one RPC function that clients can call.
Scanner enforces that every endpoint’s return shape is Result(ok, err),
so the two halves are stored separately rather than under a broader
FieldType that would force every consumer to re-pattern-match.
pub type HandlerEndpoint {
HandlerEndpoint(
module_path: String,
fn_name: String,
return_ok: field_type.FieldType,
return_err: field_type.FieldType,
params: List(#(String, field_type.FieldType)),
mutates_context: Bool,
)
}
Constructors
-
HandlerEndpoint( module_path: String, fn_name: String, return_ok: field_type.FieldType, return_err: field_type.FieldType, params: List(#(String, field_type.FieldType)), mutates_context: Bool, )Arguments
- module_path
-
Handler module path, e.g. “server/handler”
- fn_name
-
Function name, e.g. “get_items”
- return_ok
-
Ok payload of the handler’s
Result, with module-qualified user types resolved to their full path. - return_err
-
Err payload of the handler’s
Result. - params
-
Parameters excluding HandlerContext, with labels and resolved types. Each entry is #(label, FieldType).
- mutates_context
-
True when the handler returns
#(Result(_, _), HandlerContext), signalling it may have produced a new context value (e.g. a login handler that swaps the session). False when the handler returns a bareResult(_, _); codegen then threads the inbound context through unchanged. The two shapes are equivalent on the wire — this flag controls only how generated dispatch invokes the handler.
Values
pub fn build_alias_resolution_map(
imports: List(glance.Definition(glance.Import)),
) -> dict.Dict(String, String)
Build a map from import aliases (and bare module names) to the full
module path. e.g. import shared/line_items_report as wire produces
{“wire”: “shared/line_items_report”}. Unaliased imports produce
identity entries keyed by the last segment.
pub fn build_type_alias_originals(
imports: List(glance.Definition(glance.Import)),
) -> dict.Dict(String, String)
Map locally-bound type names back to their original names from the
source module. Only populated when an import uses type X as Y.
e.g. import shared/items.{type Item as MyItem} produces
{“MyItem”: “Item”}. Used by all_types_shared so an aliased type
resolves against shared_types (which holds original names).
pub fn build_type_import_map(
imports: List(glance.Definition(glance.Import)),
) -> dict.Dict(String, String)
Build a map from unqualified type names (using the alias if present)
to the FULL module path of their import.
e.g. import shared/items.{type Item} produces {“Item”: “shared/items”}.
e.g. import shared/items.{type Item as MyItem} produces
{“MyItem”: “shared/items”}.
Used by structured type resolution where downstream codegen needs the
full path for decoder function naming.
pub fn derive_module_path(file_path file_path: String) -> String
Derive the Gleam module path from a file path by finding the last
occurrence of /src/ and taking everything after it, then stripping
the .gleam extension. Splitting on the LAST /src/ (not the first)
matters for vendored paths like vendor/x/src/lib/src/types.gleam,
where the leftmost match would yield the wrong module path.
E.g. examples/checklist/shared/src/shared/items.gleam -> shared/items.
pub fn parse_module(
file_path file_path: String,
) -> Result(glance.Module, gen_error.GenError)
Read a .gleam file and parse it via glance, surfacing both I/O and
parser failures as GenError variants tagged with the file path.
Shared by the handler scanner and the type walker so every codegen
stage produces consistent errors for the same file.
pub fn scan_handler_endpoints(
server_src server_src: String,
shared_src shared_src: String,
) -> Result(List(HandlerEndpoint), List(gen_error.GenError))
Scan server source for handler endpoint functions. A handler endpoint is any public function whose last parameter is typed as HandlerContext, return type is #(something, HandlerContext), and all types in params/return are from shared/ or builtins.
pub fn walk_directory(
path path: String,
) -> Result(List(String), gen_error.GenError)
Recursively walk a directory, returning every .gleam file found.
Skips any subdirectory named generated, since libero never reads its
own output, and leaving this convention in place means consumers
don’t need to configure scan_excludes as their projects grow.
Results are sorted alphabetically so codegen output is deterministic across runs and across machines (filesystem order is not stable).