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 {
|
fn RouteWithContext(comptime Context: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const Handler = fn (Context) void;
|
pub const Handler = fn (Context) void;
|
||||||
|
|
||||||
path: []const u8,
|
path_segments: []const []const u8,
|
||||||
method: http.Method,
|
method: http.Method,
|
||||||
handler: Handler,
|
handler: Handler,
|
||||||
|
|
||||||
pub fn bind(method: http.Method, comptime path: []const u8, handler: Handler) Self {
|
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 {
|
fn matchesPath(self: *const Self, request_path: []const u8) bool {
|
||||||
var route_segs = PathIter.from(self.path);
|
var request_segments = PathIter.from(request_path);
|
||||||
var path_segs = PathIter.from(path);
|
|
||||||
|
|
||||||
var r = route_segs.next();
|
for (self.path_segments) |route_seg| {
|
||||||
var p = path_segs.next();
|
const request_seg = request_segments.next() orelse return false;
|
||||||
while (r != null and p != null) : ({
|
if (!ciutf8.eql(route_seg, request_seg)) return false;
|
||||||
r = route_segs.next();
|
|
||||||
p = path_segs.next();
|
|
||||||
}) {
|
|
||||||
if (!ciutf8.eql(r.?, p.?)) 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());
|
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 {
|
fn expectEqualRoute(expected: RouteWithContext(Context), actual: RouteWithContext(Context)) !void {
|
||||||
try std.testing.expectEqual(expected.method, actual.method);
|
try std.testing.expectEqual(expected.method, actual.method);
|
||||||
try std.testing.expectEqual(expected.handler, actual.handler);
|
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" {
|
test "RouteWithContext(T).bind" {
|
||||||
|
@ -137,7 +162,7 @@ const _tests = struct {
|
||||||
|
|
||||||
try expectEqualRoute(R{
|
try expectEqualRoute(R{
|
||||||
.method = .GET,
|
.method = .GET,
|
||||||
.path = "//ab//cd",
|
.path_segments = &[_][]const u8{ "ab", "cd" },
|
||||||
.handler = dummyHandler,
|
.handler = dummyHandler,
|
||||||
}, r);
|
}, r);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue