Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

Component

Uri.Component
pub const Component = union(enum)

File

lib/std/Uri.zig:23

Code

pub const Component = union(enum) {
    /// Invalid characters in this component must be percent encoded
    /// before being printed as part of a URI.
    raw: []const u8,
    /// This component is already percent-encoded, it can be printed
    /// directly as part of a URI.
    percent_encoded: []const u8,

    pub const empty: Component = .{ .percent_encoded = "" };

    pub fn isEmpty(component: Component) bool {
        return switch (component) {
            .raw, .percent_encoded => |string| string.len == 0,
        };
    }

    /// Returned value may point into `buffer` or be the original string.
    pub fn toRaw(component: Component, buffer: []u8) error{NoSpaceLeft}![]const u8 {
        return switch (component) {
            .raw => |raw| raw,
            .percent_encoded => |percent_encoded| if (std.mem.findScalar(u8, percent_encoded, '%')) |_|
                try std.fmt.bufPrint(buffer, "{f}", .{std.fmt.alt(component, .formatRaw)})
            else
                percent_encoded,
        };
    }

    /// Allocates the result with `arena` only if needed, so the result should not be freed.
    pub fn toRawMaybeAlloc(component: Component, arena: Allocator) Allocator.Error![]const u8 {
        return switch (component) {
            .raw => |raw| raw,
            .percent_encoded => |percent_encoded| if (std.mem.findScalar(u8, percent_encoded, '%')) |_|
                try std.fmt.allocPrint(arena, "{f}", .{std.fmt.alt(component, .formatRaw)})
            else
                percent_encoded,
        };
    }

    pub fn formatRaw(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try w.writeAll(raw),
            .percent_encoded => |percent_encoded| {
                var start: usize = 0;
                var index: usize = 0;
                while (std.mem.findScalarPos(u8, percent_encoded, index, '%')) |percent| {
                    index = percent + 1;
                    if (percent_encoded.len - index < 2) continue;
                    const percent_encoded_char =
                        std.fmt.parseInt(u8, percent_encoded[index..][0..2], 16) catch continue;
                    try w.print("{s}{c}", .{
                        percent_encoded[start..percent],
                        percent_encoded_char,
                    });
                    start = percent + 3;
                    index = percent + 3;
                }
                try w.writeAll(percent_encoded[start..]);
            },
        }
    }

    pub fn formatEscaped(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try percentEncode(w, raw, isUnreserved),
            .percent_encoded => |percent_encoded| try w.writeAll(percent_encoded),
        }
    }

    pub fn formatUser(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try percentEncode(w, raw, isUserChar),
            .percent_encoded => |percent_encoded| try w.writeAll(percent_encoded),
        }
    }

    pub fn formatPassword(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try percentEncode(w, raw, isPasswordChar),
            .percent_encoded => |percent_encoded| try w.writeAll(percent_encoded),
        }
    }

    pub fn formatHost(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try percentEncode(w, raw, isHostChar),
            .percent_encoded => |percent_encoded| try w.writeAll(percent_encoded),
        }
    }

    pub fn formatPath(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try percentEncode(w, raw, isPathChar),
            .percent_encoded => |percent_encoded| try w.writeAll(percent_encoded),
        }
    }

    pub fn formatQuery(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try percentEncode(w, raw, isQueryChar),
            .percent_encoded => |percent_encoded| try w.writeAll(percent_encoded),
        }
    }

    pub fn formatFragment(component: Component, w: *Writer) Writer.Error!void {
        switch (component) {
            .raw => |raw| try percentEncode(w, raw, isFragmentChar),
            .percent_encoded => |percent_encoded| try w.writeAll(percent_encoded),
        }
    }

    pub fn percentEncode(w: *Writer, raw: []const u8, comptime isValidChar: fn (u8) bool) Writer.Error!void {
        var start: usize = 0;
        for (raw, 0..) |char, index| {
            if (isValidChar(char)) continue;
            try w.print("{s}%{X:0>2}", .{ raw[start..index], char });
            start = index + 1;
        }
        try w.writeAll(raw[start..]);
    }
}