Make handlers return new Response object

This commit is contained in:
jaina heartles 2022-05-23 21:58:05 -07:00
parent 004568a907
commit 407923eacd
3 changed files with 15 additions and 15 deletions

View file

@ -7,7 +7,7 @@ const Writer = std.net.Stream.Writer;
const Status = std.http.Status; const Status = std.http.Status;
const Method = std.http.Method; const Method = std.http.Method;
pub const Handler = fn (*Context) anyerror!void; pub const Handler = fn (*Context) anyerror!Response;
const HeaderMap = std.HashMap([]const u8, []const u8, struct { const HeaderMap = std.HashMap([]const u8, []const u8, struct {
pub fn eql(_: @This(), a: []const u8, b: []const u8) bool { pub fn eql(_: @This(), a: []const u8, b: []const u8) bool {
@ -197,7 +197,7 @@ pub const Context = struct {
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
}; };
pub const Response2 = struct { pub const Response = struct {
status: Status, status: Status,
headers: HeaderMap, headers: HeaderMap,
body: ?[]const u8 = null, body: ?[]const u8 = null,
@ -210,7 +210,7 @@ pub const Request2 = struct {
body: ?[]const u8 = null, body: ?[]const u8 = null,
}; };
const Response = struct { const ResponseOld = struct {
headers: HeaderMap, headers: HeaderMap,
writer: Writer, writer: Writer,

View file

@ -81,10 +81,9 @@ pub fn main() anyerror!void {
// todo: keep track of connections // todo: keep track of connections
_ = async http.handleConnection(conn, struct { _ = async http.handleConnection(conn, struct {
fn func(ctx: *http.Context) anyerror!void { fn func(ctx: *http.Context) anyerror!http.Response {
try router(ctx.request.method, ctx.request.path, ctx); return try router(ctx.request.method, ctx.request.path, ctx);
_ = ctx; //_ = ctx;
return;
} }
}.func); }.func);
} }

View file

@ -1,4 +1,5 @@
const std = @import("std"); const std = @import("std");
const http = @import("./http.zig");
const ciutf8 = @import("./util.zig").ciutf8; const ciutf8 = @import("./util.zig").ciutf8;
const PathIter = struct { const PathIter = struct {
@ -70,17 +71,17 @@ const RouteSegment = union(enum) {
}; };
pub fn RouteFn(comptime Context: type) type { pub fn RouteFn(comptime Context: type) type {
return fn (Context, std.http.Method, []const u8) anyerror!void; return fn (Context, std.http.Method, []const u8) anyerror!http.Response;
} }
/// `makeRoute` takes a route definition and a handler of the form `fn(<Context>, <Params>) anyerror!void` /// `makeRoute` takes a route definition and a handler of the form `fn(<Context>, <Params>) anyerror!http.Response`
/// where `Params` is a struct containing one field of type `[]const u8` for each path parameter /// where `Params` is a struct containing one field of type `[]const u8` for each path parameter
/// ///
/// Arguments: /// Arguments:
/// method: The HTTP method to match /// method: The HTTP method to match
/// path: The path spec to match against. Path segments beginning with a `:` will cause the rest of /// path: The path spec to match against. Path segments beginning with a `:` will cause the rest of
/// the segment to be treated as the name of a path parameter /// the segment to be treated as the name of a path parameter
/// handler: The code to execute on route match. This must be a function of form `fn(<Context>, <Params>) anyerror!void` /// handler: The code to execute on route match. This must be a function of form `fn(<Context>, <Params>) anyerror!http.Response`
/// ///
/// Implicit Arguments: /// Implicit Arguments:
/// Context: the type of a user-supplied Context that is passed through the route. typically `std.http.Context` but /// Context: the type of a user-supplied Context that is passed through the route. typically `std.http.Context` but
@ -90,7 +91,7 @@ pub fn RouteFn(comptime Context: type) type {
/// `[]const u8` and it must have the same name as a single path parameter. /// `[]const u8` and it must have the same name as a single path parameter.
/// ///
/// Returns: /// Returns:
/// A new route function of type `fn(<Context>, std.http.Method, []const u8) anyerror!void`. When called, /// A new route function of type `fn(<Context>, std.http.Method, []const u8) anyerror!http.Response`. When called,
/// this function will test the provided values against its specification. If they match, then /// this function will test the provided values against its specification. If they match, then
/// this function will parse path parameters and <handler> will be called with the supplied /// this function will parse path parameters and <handler> will be called with the supplied
/// context and params. If they do not match, this function will return error.Http404 /// context and params. If they do not match, this function will return error.Http404
@ -138,7 +139,7 @@ pub fn makeRoute(
} }
return struct { return struct {
fn func(ctx: Context, req_method: std.http.Method, req_path: []const u8) anyerror!void { fn func(ctx: Context, req_method: std.http.Method, req_path: []const u8) anyerror!http.Response {
if (req_method != method) return error.Http404; if (req_method != method) return error.Http404;
var params: Params = undefined; var params: Params = undefined;
@ -164,7 +165,7 @@ pub fn makeRoute(
} }
pub fn RouterFn(comptime Context: type) type { pub fn RouterFn(comptime Context: type) type {
return fn (std.http.Method, path: []const u8, Context) anyerror!void; return fn (std.http.Method, path: []const u8, Context) anyerror!http.Response;
} }
pub fn makeRouter( pub fn makeRouter(
@ -172,7 +173,7 @@ pub fn makeRouter(
comptime routes: []const RouteFn(Context), comptime routes: []const RouteFn(Context),
) RouterFn(Context) { ) RouterFn(Context) {
return struct { return struct {
fn dispatch(method: std.http.Method, path: []const u8, ctx: Context) anyerror!void { fn dispatch(method: std.http.Method, path: []const u8, ctx: Context) anyerror!http.Response {
for (routes) |r| { for (routes) |r| {
return r(ctx, method, path) catch |err| switch (err) { return r(ctx, method, path) catch |err| switch (err) {
error.Http404 => continue, error.Http404 => continue,
@ -298,7 +299,7 @@ const _tests = struct {
fn dummyHandler(comptime Args: type) type { fn dummyHandler(comptime Args: type) type {
comptime { comptime {
return struct { return struct {
fn func(_: TestContext, _: Args) anyerror!void {} fn func(_: TestContext, _: Args) anyerror!http.Response {}
}; };
} }
} }