const std = @import("std"); const Response = @import("../Response.zig"); const Route = @import("../Route.zig"); const Parameter = @import("../Parameter.zig"); const Interface = @import("Interface.zig"); pub fn Context(comptime r: anytype) type { return struct { pub const route = Route.fromAny(r); pub const Params = Parameter.Struct(route); pub const Request = struct { base_request: *std.http.Server.Request, params: Params, arena: std.mem.Allocator, gpa: std.mem.Allocator, io: std.Io, /// Parses the body of the request and returns type `T`. /// The arena allocator will be used to do the parsing. pub fn json(self: @This(), T: type) !T { var buffer: [1024]u8 = undefined; var reader = std.json.Reader.init(self.arena, self.base_request.readerExpectNone(&buffer)); return std.json.parseFromTokenSourceLeaky(T, self.arena, &reader, .{}); } }; const badRequest = struct { pub fn badRequest(_: Request) Response { return .with(.bad_request, .string("method does not exist")); } }.badRequest; get: *const fn (Request) Response = badRequest, post: *const fn (Request) Response = badRequest, delete: *const fn (Request) Response = badRequest, head: *const fn (Request) Response = badRequest, put: *const fn (Request) Response = badRequest, connect: *const fn (Request) Response = badRequest, options: *const fn (Request) Response = badRequest, trace: *const fn (Request) Response = badRequest, patch: *const fn (Request) Response = badRequest, pub fn handle( self: *const @This(), gpa: std.mem.Allocator, arena: std.mem.Allocator, io: std.Io, request: *std.http.Server.Request, ) Response { const req: Request = .{ .base_request = request, .arena = arena, .gpa = gpa, .io = io, .params = Parameter.parse(Params, &route, request.head.target), }; return (switch (request.head.method) { .GET => self.get, .POST => self.post, .DELETE => self.delete, .HEAD => self.head, .PUT => self.put, .CONNECT => self.connect, .OPTIONS => self.options, .TRACE => self.trace, .PATCH => self.patch, })(req); } pub fn interface(self: *const @This()) Interface { return .from(self, route); } }; }