diff options
Diffstat (limited to 'src/http/Route.zig')
| -rw-r--r-- | src/http/Route.zig | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/src/http/Route.zig b/src/http/Route.zig index bc86544..f979d04 100644 --- a/src/http/Route.zig +++ b/src/http/Route.zig @@ -14,14 +14,16 @@ pub const Segment = union(enum) { segments: []const Segment, +pub const index: @This() = .{ .segments = &.{} }; + pub fn fromAny(comptime route: anytype) @This() { var segments: []const Segment = &.{}; - inline for(route) |r| { - const segment: []const Segment = &.{ switch (@TypeOf(r)) { + inline for (route) |r| { + const segment: []const Segment = &.{switch (@TypeOf(r)) { @EnumLiteral() => .{ .identifier = @tagName(r) }, else => .{ .literal = r }, - } }; + }}; segments = segments ++ segment; } @@ -35,11 +37,55 @@ pub fn format(self: *const @This(), writer: *std.Io.Writer) !void { } } +pub fn isPrefixOf(self: *const @This(), other: *const @This()) bool { + if (self.segments.len > other.segments.len) { + return false; + } + + for (self.segments, other.segments[0..self.segments.len]) |s, o| { + if (std.meta.activeTag(s) != std.meta.activeTag(o)) { + return false; + } + + if (s == .literal) { + if (!std.mem.eql(u8, s.literal, o.literal)) { + return false; + } + } + } + + return true; +} + +pub fn equals(self: *const @This(), other: *const @This()) bool { + if (self.segments.len != other.segments.len) { + return false; + } -pub fn shift(self: *const @This()) struct { Segment, @This() } { - if (self.segments.len == 0) { - @compileError("shift on empty route"); + for (self.segments, other.segments) |s, o| { + if (std.meta.activeTag(s) != std.meta.activeTag(o)) { + return false; + } + + if (s == .literal) { + if (!std.mem.eql(u8, s.literal, o.literal)) { + return false; + } + } } - return .{ self.segments[0], self.segments[1..] }; + return true; +} + +test "isPrefixOf" { + { + const parent = comptime fromAny(.{ "api", "images", .id }); + const child = comptime fromAny(.{ "api", "images", .id, "metadata" }); + try std.testing.expect(parent.isPrefixOf(&child)); + } + { + const parent = comptime fromAny(.{ "api", "videos", .id }); + const child = comptime fromAny(.{ "api", "images", .id, "metadata" }); + try std.testing.expect(!parent.isPrefixOf(&child)); + } } |