libero/codegen

Cross-cutting helpers used by every codegen submodule.

File I/O, path utilities, naming helpers, and small predicates over field_type.FieldType graphs. The actual generators live in the per-domain modules (codegen_dispatch, codegen_stubs, codegen_decoders, codegen_server).

Values

pub fn collect_endpoint_type_imports(
  endpoints endpoints: List(scanner.HandlerEndpoint),
  include_return include_return: Bool,
) -> List(String)

Collect import <module> lines for every shared module path referenced (transitively) by the endpoints’ parameter types and, optionally, return types. Output is unique and sorted.

pub fn emit_client_msg_variants(
  endpoints endpoints: List(scanner.HandlerEndpoint),
) -> List(String)

Emit the body lines of the generated ClientMsg type — one variant per endpoint, indented by two spaces. Both the server dispatch and the client stubs need this exact shape; routing both through this helper guarantees they stay in sync (mismatched variants would silently break the wire contract).

pub fn endpoints_contain(
  endpoints endpoints: List(scanner.HandlerEndpoint),
  predicate predicate: fn(field_type.FieldType) -> Bool,
) -> Bool

True if any endpoint’s parameter or return type (transitively) satisfies predicate. Used for stdlib import detection (Option, Dict).

pub fn ensure_parent_dir(path path: String) -> Nil

Create the parent directory for the given file path, ignoring any error. create_directory_all is idempotent (no error if the dir already exists) and any real write failure surfaces on the subsequent simplifile.write call.

pub fn extract_dir(path: String) -> String

Strip the final path segment, returning the directory portion of path. Returns “.” when there’s no parent (single-segment input).

pub fn import_if(
  endpoints endpoints: List(scanner.HandlerEndpoint),
  predicate predicate: fn(field_type.FieldType) -> Bool,
  import_line import_line: String,
) -> String

Emit import_line (with a leading newline) iff any endpoint type transitively satisfies predicate; otherwise the empty string. Used for conditional stdlib imports like gleam/dict or gleam/option.

pub fn is_dict(ft: field_type.FieldType) -> Bool
pub fn is_option(ft: field_type.FieldType) -> Bool
pub fn last_split(
  input input: String,
  separator separator: String,
) -> String

Take the substring after the LAST occurrence of separator in input. Falls back to input if the separator is absent. Splitting on the last occurrence (not the first) matters for nested paths like vendor/x/src/inner/src/types, where the leftmost match would yield the wrong segment.

pub fn module_to_mjs_path(module_path: String) -> String

Convert a Gleam module path like “shared/discount” to its compiled .mjs bundle path “shared/shared/discount.mjs”. The first segment is the package name (Gleam convention) and is repeated because the bundle layout is <package>/<module_path>.mjs.

pub fn module_to_underscored(module_path: String) -> String

Convert a Gleam module path like “shared/discount” to a flat underscore-separated alias suitable for use as a Gleam identifier or import alias suffix. e.g. “shared/discount” -> “shared_discount”.

pub fn to_pascal_case(name: String) -> String

Convert a snake_case name to PascalCase. e.g. “get_items” -> “GetItems”, “create_item” -> “CreateItem”

pub fn variant_pattern(
  variant_name variant_name: String,
  params params: List(#(String, field_type.FieldType)),
) -> String

Emit a constructor / pattern shape like Variant(label1:, label2:) or just Variant when there are no parameters. Used by both the dispatch match arms (destructure) and client stubs (constructor call).

pub fn write_file(
  path path: String,
  content content: String,
) -> Result(Nil, gen_error.GenError)

Write content to a file, logging the path on success. Gleam files are run through gleam format before writing.

Search Document