@@ -25,9 +25,6 @@ pub const RouterFn = *const fn (*Frame, RouteFn) BuildFn;
/// TODO document
const Router = @This();
/// TODO document
pub const UriIterator = std.mem.SplitIterator(u8, .scalar);
/// The Verse router will scan through an array of Match structs looking for a
/// given name. Verse doesn't assert that the given name will match a director
/// or endpoint/page specifically. e.g. `/uri/page` and `/uri/page/` will both
@@ -342,6 +339,19 @@ pub fn defaultBuilder(vrs: *Frame, build: BuildFn) void {
};
}
/// Note UriIterator is a simple split iterator an not a token iterator. If
/// you're using a custom routing implementation; this may not be the behavior
/// you expect. e.g. for a uri = `////word/end` the first 3 calls to next() will
/// return "". Typically this isn't the expected behavior for a directory
/// structure and `////word/end` should be equivalent to `/word/end`. Verse
/// doesn't enforce this behavior to enable cases where the expected value of
/// `/missing/expected/prefix/word/end` has 3 omitted/empty values.
pub const UriIterator = std.mem.SplitIterator(u8, .scalar);
/// splitUri will take any uri, do the most basic of input validation and then
/// return UriIterator.
///
/// Note: UriIterator does not behave like a normal token iterator.
pub fn splitUri(uri: []const u8) !UriIterator {
if (uri.len == 0 or uri[0] != '/') return error.InvalidUri;
return .{
@@ -382,6 +392,8 @@ pub fn testingRouter(frame: *Frame) RoutingError!BuildFn {
test "uri" {
const uri_file = "/root/first/second/third";
const uri_dir = "/root/first/second/";
const uri_broken = "/root/first/////sixth/";
const uri_dots = "/root/first/../../../fifth";
var itr = try splitUri(uri_file);
try std.testing.expectEqualStrings("root", itr.next().?);
@@ -396,6 +408,26 @@ test "uri" {
try std.testing.expectEqualStrings("second", itr.next().?);
try std.testing.expectEqualStrings("", itr.next().?);
try std.testing.expectEqual(null, itr.next());
itr = try splitUri(uri_broken);
try std.testing.expectEqualStrings("root", itr.next().?);
try std.testing.expectEqualStrings("first", itr.next().?);
try std.testing.expectEqualStrings("", itr.next().?);
try std.testing.expectEqualStrings("", itr.next().?);
try std.testing.expectEqualStrings("", itr.next().?);
try std.testing.expectEqualStrings("", itr.next().?);
try std.testing.expectEqualStrings("sixth", itr.next().?);
try std.testing.expectEqualStrings("", itr.next().?);
try std.testing.expectEqual(null, itr.next());
itr = try splitUri(uri_dots);
try std.testing.expectEqualStrings("root", itr.next().?);
try std.testing.expectEqualStrings("first", itr.next().?);
try std.testing.expectEqualStrings("..", itr.next().?);
try std.testing.expectEqualStrings("..", itr.next().?);
try std.testing.expectEqualStrings("..", itr.next().?);
try std.testing.expectEqualStrings("fifth", itr.next().?);
try std.testing.expectEqual(null, itr.next());
}
const std = @import("std");