glimr/routing/compiler

Route Compiler

Turns controller annotations into a generated Gleam file with a big case expression that dispatches requests by path and method. This is the heart of the route system — it validates everything (handler params match route segments, required imports exist) before generating code, so developers get clear errors at compile time instead of runtime crashes.

Types

Everything write_compiled_file needs to assemble the final .gleam file — imports, the case expression body, which HTTP methods are used (for the http import), and a line-to-route mapping so compile errors can point at the original route annotation instead of the generated code.

pub type CompileResult {
  CompileResult(
    imports: List(String),
    routes_code: String,
    used_methods: List(String),
    uses_middleware: Bool,
    uses_ctx: Bool,
    line_to_route: dict.Dict(Int, String),
  )
}

Constructors

  • CompileResult(
      imports: List(String),
      routes_code: String,
      used_methods: List(String),
      uses_middleware: Bool,
      uses_ctx: Bool,
      line_to_route: dict.Dict(Int, String),
    )

Values

pub fn compile_routes(
  controller_results: List(
    #(String, annotation_parser.ParseResult),
  ),
) -> Result(CompileResult, String)

The main entry point — takes every controller’s parsed annotations and produces the Gleam code that dispatches requests. Runs all validation first (paths, handler params, imports) so developers get clear errors before any code is generated.

pub fn write_compiled_file(
  compile_result: CompileResult,
  dest_path: String,
) -> Result(Nil, String)

Takes the compiled result and writes the actual .gleam file. Runs gleam check before formatting so that if the generated code has type errors, the line numbers in the error still match our line-to-route mapping — formatting would shift everything around. If check fails, the previous file content is restored so a bad compile never leaves a broken file on disk.

Search Document