const std = @import("std"); pub const HandlerInfo = @import("handler-info.zig"); pub const api = @import("api/root.zig"); pub const static: HandlerInfo = .from_type(@import("static.zig")); const routes = (Routes {}) .with("", static) .with_module("/api", api); pub const handlers = std.StaticStringMap(HandlerInfo).initComptime(routes.items); pub fn get(path: []const u8) HandlerInfo { return (handlers.getLongestPrefix(std.mem.trimEnd(u8, path, "/")) orelse unreachable).value; } const Routes = struct { const Self = @This(); const Route = struct{ []const u8, HandlerInfo }; items: []const Route = &[0]Route{}, pub fn with(self: Self, comptime route: []const u8, handler: HandlerInfo) Self { var next = self; const tail: []const Route = &[1]Route { .{ route, handler } }; next.items = self.items ++ tail; return next; } pub fn with_module(self: Self, comptime prefix: []const u8, module: type) Self { var next = self; if (@typeInfo(module) != .@"struct") return self; inline for (@typeInfo(module).@"struct".decls) |decl| { const field = @field(module, decl.name); const route = prefix ++ "/" ++ decl.name; switch (@TypeOf(field)) { type => next = next.with_module(route, field), HandlerInfo => next = next.with(route, field), else => {}, } } return next; } };