Turn routers into functions

This commit is contained in:
jaina heartles 2022-05-22 13:07:30 -07:00
parent b2430b333c
commit f2aec8249b

View file

@ -168,11 +168,13 @@ fn makeRoute(
}.func;
}
pub fn Router(comptime Context: type, comptime routes: []const Route(Context)) type {
return struct {
const Self = @This();
fn RouterFn(comptime Context: type) type {
return fn (http.Method, path: []const u8, Context) HttpError!void;
}
pub fn dispatch(_: *const Self, method: http.Method, path: []const u8, ctx: Context) HttpError!void {
pub fn makeRouter(comptime Context: type, comptime routes: []const Route(Context)) RouterFn(Context) {
return struct {
fn dispatch(method: http.Method, path: []const u8, ctx: Context) HttpError!void {
for (routes) |r| {
return r(ctx, method, path) catch |err| switch (err) {
error.Http404 => continue,
@ -182,7 +184,7 @@ pub fn Router(comptime Context: type, comptime routes: []const Route(Context)) t
return error.Http404;
}
};
}.dispatch;
}
test {
@ -312,18 +314,18 @@ const _tests = struct {
makeRoute(.GET, "/b", mock_b.func),
};
const router = Router(TestContext, &routes){};
_ = try router.dispatch(.GET, "/a", 10);
const router = makeRouter(TestContext, &routes);
_ = try router(.GET, "/a", 10);
try mock_a.expectCalledOnceWith(10, .{});
try mock_b.expectNotCalled();
mock_a.reset();
_ = try router.dispatch(.GET, "/b", 0);
_ = try router(.GET, "/b", 0);
try mock_a.expectNotCalled();
try mock_b.expectCalledOnceWith(0, .{});
mock_b.reset();
try std.testing.expectError(error.Http404, router.dispatch(.GET, "/c", 0));
try std.testing.expectError(error.Http404, router(.GET, "/c", 0));
}
test "Router(T).dispatch same path different methods" {
@ -335,13 +337,13 @@ const _tests = struct {
makeRoute(.POST, "/a", mock_post.func),
};
const router = Router(TestContext, &routes){};
_ = try router.dispatch(.GET, "/a", 10);
const router = makeRouter(TestContext, &routes);
_ = try router(.GET, "/a", 10);
try mock_get.expectCalledOnceWith(10, .{});
try mock_post.expectNotCalled();
mock_get.reset();
_ = try router.dispatch(.POST, "/a", 10);
_ = try router(.POST, "/a", 10);
try mock_get.expectNotCalled();
try mock_post.expectCalledOnceWith(10, .{});
}
@ -355,13 +357,13 @@ const _tests = struct {
makeRoute(.GET, "/a/b", mock_b.func),
};
const router = Router(TestContext, &routes){};
_ = try router.dispatch(.GET, "/a", 10);
const router = makeRouter(TestContext, &routes);
_ = try router(.GET, "/a", 10);
try mock_a.expectCalledOnceWith(10, .{});
try mock_b.expectNotCalled();
mock_a.reset();
_ = try router.dispatch(.GET, "/a/b", 11);
_ = try router(.GET, "/a/b", 11);
try mock_a.expectNotCalled();
try mock_b.expectCalledOnceWith(11, .{});
}
@ -373,12 +375,12 @@ const _tests = struct {
makeRoute(.GET, "/test/a", mock_a.func),
};
const router = Router(TestContext, &routes){};
_ = try router.dispatch(.GET, "/TEST/A", 10);
const router = makeRouter(TestContext, &routes);
_ = try router(.GET, "/TEST/A", 10);
try mock_a.expectCalledOnceWith(10, .{});
mock_a.reset();
_ = try router.dispatch(.GET, "/TesT/a", 11);
_ = try router(.GET, "/TesT/a", 11);
try mock_a.expectCalledOnceWith(11, .{});
}
@ -389,16 +391,16 @@ const _tests = struct {
makeRoute(.GET, "/test/a", mock_a.func),
};
const router = Router(TestContext, &routes){};
_ = try router.dispatch(.GET, "/test//a", 10);
const router = makeRouter(TestContext, &routes);
_ = try router(.GET, "/test//a", 10);
try mock_a.expectCalledOnceWith(10, .{});
mock_a.reset();
_ = try router.dispatch(.GET, "//test///////////a////", 11);
_ = try router(.GET, "//test///////////a////", 11);
try mock_a.expectCalledOnceWith(11, .{});
mock_a.reset();
_ = try router.dispatch(.GET, "test/a", 12);
_ = try router(.GET, "test/a", 12);
try mock_a.expectCalledOnceWith(12, .{});
}
@ -411,17 +413,17 @@ const _tests = struct {
makeRoute(.GET, "/test/:a_id/abcd/:b_id", mock_b.func),
};
const router = Router(TestContext, &routes){};
_ = try router.dispatch(.GET, "/test/xyz/abcd", 10);
const router = makeRouter(TestContext, &routes);
_ = try router(.GET, "/test/xyz/abcd", 10);
try mock_a.expectCalledOnceWith(10, .{ .id = "xyz" });
try mock_b.expectNotCalled();
mock_a.reset();
try std.testing.expectError(error.Http404, router.dispatch(.GET, "/test//abcd", 10));
try std.testing.expectError(error.Http404, router(.GET, "/test//abcd", 10));
try mock_a.expectNotCalled();
try mock_b.expectNotCalled();
_ = try router.dispatch(.GET, "/test/xyz/abcd/zyx", 10);
_ = try router(.GET, "/test/xyz/abcd/zyx", 10);
try mock_a.expectNotCalled();
try mock_b.expectCalledOnceWith(10, .{ .a_id = "xyz", .b_id = "zyx" });
}