update names

This commit is contained in:
jaina heartles 2022-05-22 13:17:46 -07:00
parent f2aec8249b
commit 9e3cb40fca

View file

@ -70,15 +70,15 @@ const RouteSegment = union(enum) {
param: []const u8,
};
// convention: return HttpError IFF a status you can't handle happens.
// convention: return HttpError IFF a situation you can't finish the request in happens.
// If status line/headers were written, always return void
const HttpError = error{Http404};
fn Route(comptime Context: type) type {
fn RouteFn(comptime Context: type) type {
return fn (Context, http.Method, []const u8) HttpError!void;
}
/// `makeRoute` takes a route definition and a handler of the form `fn(<Context>, <Params>) HttpError`
/// `makeRoute` takes a route definition and a handler of the form `fn(<Context>, <Params>) HttpError!void`
/// where `Params` is a struct containing one field of type `[]const u8` for each path parameter
///
/// Arguments:
@ -95,10 +95,10 @@ fn Route(comptime Context: type) type {
/// `[]const u8` and it must have the same name as a single path parameter.
///
/// Returns:
/// A new route function of type `fn(<Context>, http.Method, []const u8) ?HttpError`. When called,
/// A new route function of type `fn(<Context>, http.Method, []const u8) HttpError!void`. When called,
/// 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
/// context and params. If they do not match, this function will return null
/// context and params. If they do not match, this function will return error.Http404
///
/// Example:
/// route(.GET, "/user/:id/followers", struct{
@ -112,7 +112,7 @@ fn makeRoute(
) return_type: {
const handler_info = @typeInfo(@TypeOf(handler));
if (handler_info != .Fn) @compileError("Route expects a function");
break :return_type Route(@typeInfo(@TypeOf(handler)).Fn.args[0].arg_type.?);
break :return_type RouteFn(@typeInfo(@TypeOf(handler)).Fn.args[0].arg_type.?);
} {
const handler_args = @typeInfo(@TypeOf(handler)).Fn.args;
if (handler_args.len != 2) @compileError("handler function must have signature fn(Context, Params) HttpError");
@ -172,7 +172,10 @@ fn RouterFn(comptime Context: type) type {
return fn (http.Method, path: []const u8, Context) HttpError!void;
}
pub fn makeRouter(comptime Context: type, comptime routes: []const Route(Context)) RouterFn(Context) {
pub fn makeRouter(
comptime Context: type,
comptime routes: []const RouteFn(Context),
) RouterFn(Context) {
return struct {
fn dispatch(method: http.Method, path: []const u8, ctx: Context) HttpError!void {
for (routes) |r| {
@ -305,11 +308,11 @@ const _tests = struct {
}
}
test "Router(T).dispatch" {
test "makeRoute(T, ...)" {
const mock_a = CallTracker(.{}, dummyHandler(DummyArgs).func);
const mock_b = CallTracker(.{}, dummyHandler(DummyArgs).func);
const routes = comptime [_]Route(TestContext){
const routes = comptime [_]RouteFn(TestContext){
makeRoute(.GET, "/a", mock_a.func),
makeRoute(.GET, "/b", mock_b.func),
};
@ -328,11 +331,11 @@ const _tests = struct {
try std.testing.expectError(error.Http404, router(.GET, "/c", 0));
}
test "Router(T).dispatch same path different methods" {
test "makeRoute(T, ...) same path different methods" {
const mock_get = CallTracker(.{}, dummyHandler(DummyArgs).func);
const mock_post = CallTracker(.{}, dummyHandler(DummyArgs).func);
const routes = comptime [_]Route(TestContext){
const routes = comptime [_]RouteFn(TestContext){
makeRoute(.GET, "/a", mock_get.func),
makeRoute(.POST, "/a", mock_post.func),
};
@ -348,11 +351,11 @@ const _tests = struct {
try mock_post.expectCalledOnceWith(10, .{});
}
test "Router(T).dispatch route under subpath" {
test "makeRoute(T, ...) route under subpath" {
const mock_a = CallTracker(.{}, dummyHandler(DummyArgs).func);
const mock_b = CallTracker(.{}, dummyHandler(DummyArgs).func);
const routes = comptime [_]Route(TestContext){
const routes = comptime [_]RouteFn(TestContext){
makeRoute(.GET, "/a", mock_a.func),
makeRoute(.GET, "/a/b", mock_b.func),
};
@ -368,10 +371,10 @@ const _tests = struct {
try mock_b.expectCalledOnceWith(11, .{});
}
test "Router(T).dispatch case-insensitive route" {
test "makeRoute(T, ...) case-insensitive route" {
const mock_a = CallTracker(.{}, dummyHandler(DummyArgs).func);
const routes = comptime [_]Route(TestContext){
const routes = comptime [_]RouteFn(TestContext){
makeRoute(.GET, "/test/a", mock_a.func),
};
@ -384,10 +387,10 @@ const _tests = struct {
try mock_a.expectCalledOnceWith(11, .{});
}
test "Router(T).dispatch redundant /" {
test "makeRoute(T, ...) redundant /" {
const mock_a = CallTracker(.{}, dummyHandler(DummyArgs).func);
const routes = comptime [_]Route(TestContext){
const routes = comptime [_]RouteFn(TestContext){
makeRoute(.GET, "/test/a", mock_a.func),
};
@ -404,11 +407,11 @@ const _tests = struct {
try mock_a.expectCalledOnceWith(12, .{});
}
test "Router(T).dispatch with variables" {
test "makeRoute(T, ...) with variables" {
const mock_a = CallTracker(.{}, dummyHandler(struct { id: []const u8 }).func);
const mock_b = CallTracker(.{}, dummyHandler(struct { a_id: []const u8, b_id: []const u8 }).func);
const routes = comptime [_]Route(TestContext){
const routes = comptime [_]RouteFn(TestContext){
makeRoute(.GET, "/test/:id/abcd", mock_a.func),
makeRoute(.GET, "/test/:a_id/abcd/:b_id", mock_b.func),
};