const std = @import("std"); pub const Segment = union(enum) { literal: []const u8, identifier: []const u8, pub fn format(self: *const @This(), writer: *std.Io.Writer) !void { switch (self.*) { .literal => |l| try writer.print("{s}", .{l}), .identifier => |l| try writer.print("{{{s}}}", .{l}), } } }; segments: []const Segment, pub fn fromAny(comptime route: anytype) @This() { var segments: []const Segment = &.{}; inline for(route) |r| { const segment: []const Segment = &.{ switch (@TypeOf(r)) { @EnumLiteral() => .{ .identifier = @tagName(r) }, else => .{ .literal = r }, } }; segments = segments ++ segment; } return .{ .segments = segments }; } pub fn format(self: *const @This(), writer: *std.Io.Writer) !void { for (self.segments) |*seg| { try writer.print("/{f}", .{seg}); } } pub fn shift(self: *const @This()) struct { Segment, @This() } { if (self.segments.len == 0) { @compileError("shift on empty route"); } return .{ self.segments[0], self.segments[1..] }; }