Store path segments instead of path
This commit is contained in:
parent
d885dc5fc8
commit
c19cc267bf
1 changed files with 40 additions and 15 deletions
|
@ -45,33 +45,44 @@ const PathIter = struct {
|
|||
}
|
||||
};
|
||||
|
||||
fn splitPath(comptime path: []const u8) []const []const u8 {
|
||||
comptime {
|
||||
var segments: [path.len][]const u8 = undefined;
|
||||
|
||||
var iter = PathIter.from(path);
|
||||
var it = iter.next();
|
||||
var count = 0;
|
||||
while (it != null) : (it = iter.next()) {
|
||||
segments[count] = it.?;
|
||||
count += 1;
|
||||
}
|
||||
|
||||
return segments[0..count];
|
||||
}
|
||||
}
|
||||
|
||||
fn RouteWithContext(comptime Context: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
pub const Handler = fn (Context) void;
|
||||
|
||||
path: []const u8,
|
||||
path_segments: []const []const u8,
|
||||
method: http.Method,
|
||||
handler: Handler,
|
||||
|
||||
pub fn bind(method: http.Method, comptime path: []const u8, handler: Handler) Self {
|
||||
return .{ .method = method, .path = path, .handler = handler };
|
||||
return .{ .method = method, .path_segments = splitPath(path), .handler = handler };
|
||||
}
|
||||
|
||||
fn matchesPath(self: *const Self, path: []const u8) bool {
|
||||
var route_segs = PathIter.from(self.path);
|
||||
var path_segs = PathIter.from(path);
|
||||
fn matchesPath(self: *const Self, request_path: []const u8) bool {
|
||||
var request_segments = PathIter.from(request_path);
|
||||
|
||||
var r = route_segs.next();
|
||||
var p = path_segs.next();
|
||||
while (r != null and p != null) : ({
|
||||
r = route_segs.next();
|
||||
p = path_segs.next();
|
||||
}) {
|
||||
if (!ciutf8.eql(r.?, p.?)) return false;
|
||||
for (self.path_segments) |route_seg| {
|
||||
const request_seg = request_segments.next() orelse return false;
|
||||
if (!ciutf8.eql(route_seg, request_seg)) return false;
|
||||
}
|
||||
|
||||
return r == null and p == null;
|
||||
return request_segments.next() == null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -125,10 +136,24 @@ const _tests = struct {
|
|||
try std.testing.expectEqual(@as(?[]const u8, null), it.next());
|
||||
}
|
||||
|
||||
fn expectEqualSegments(expected: []const []const u8, actual: []const []const u8) !void {
|
||||
try std.testing.expectEqual(expected.len, actual.len);
|
||||
for (expected) |_, i| {
|
||||
try std.testing.expectEqualStrings(expected[i], actual[i]);
|
||||
}
|
||||
}
|
||||
|
||||
test "splitPath" {
|
||||
const path = "//ab/c/de";
|
||||
const segments = splitPath(path);
|
||||
|
||||
try expectEqualSegments(&[_][]const u8{ "ab", "c", "de" }, segments);
|
||||
}
|
||||
|
||||
fn expectEqualRoute(expected: RouteWithContext(Context), actual: RouteWithContext(Context)) !void {
|
||||
try std.testing.expectEqual(expected.method, actual.method);
|
||||
try std.testing.expectEqual(expected.handler, actual.handler);
|
||||
try std.testing.expectEqualStrings(expected.path, actual.path);
|
||||
try expectEqualSegments(expected.path_segments, actual.path_segments);
|
||||
}
|
||||
|
||||
test "RouteWithContext(T).bind" {
|
||||
|
@ -137,7 +162,7 @@ const _tests = struct {
|
|||
|
||||
try expectEqualRoute(R{
|
||||
.method = .GET,
|
||||
.path = "//ab//cd",
|
||||
.path_segments = &[_][]const u8{ "ab", "cd" },
|
||||
.handler = dummyHandler,
|
||||
}, r);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue