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.