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 bare Result(_, _); 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).

Search Document