unionstd.Uri.Component[src]

Fields

raw: []const u8

Invalid characters in this component must be percent encoded before being printed as part of a URI.

percent_encoded: []const u8

This component is already percent-encoded, it can be printed directly as part of a URI.

Values

Constantempty[src]

Source Code

Source code
pub const empty: Component = .{ .percent_encoded = "" }

Functions

FunctionisEmpty[src]

pub fn isEmpty(component: Component) bool

Parameters

component: Component

Source Code

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

FunctiontoRawMaybeAlloc[src]

pub fn toRawMaybeAlloc( component: Component, arena: std.mem.Allocator, ) std.mem.Allocator.Error![]const u8

Allocates the result with arena only if needed, so the result should not be freed.

Parameters

component: Component

Source Code

Source code
pub fn toRawMaybeAlloc(
    component: Component,
    arena: std.mem.Allocator,
) std.mem.Allocator.Error![]const u8 {
    return switch (component) {
        .raw => |raw| raw,
        .percent_encoded => |percent_encoded| if (std.mem.indexOfScalar(u8, percent_encoded, '%')) |_|
            try std.fmt.allocPrint(arena, "{raw}", .{component})
        else
            percent_encoded,
    };
}

Functionformat[src]

pub fn format( component: Component, comptime fmt_str: []const u8, _: std.fmt.FormatOptions, writer: anytype, ) @TypeOf(writer).Error!void

Parameters

component: Component
fmt_str: []const u8

Source Code

Source code
pub fn format(
    component: Component,
    comptime fmt_str: []const u8,
    _: std.fmt.FormatOptions,
    writer: anytype,
) @TypeOf(writer).Error!void {
    if (fmt_str.len == 0) {
        try writer.print("std.Uri.Component{{ .{s} = \"{}\" }}", .{
            @tagName(component),
            std.zig.fmtEscapes(switch (component) {
                .raw, .percent_encoded => |string| string,
            }),
        });
    } else if (comptime std.mem.eql(u8, fmt_str, "raw")) switch (component) {
        .raw => |raw| try writer.writeAll(raw),
        .percent_encoded => |percent_encoded| {
            var start: usize = 0;
            var index: usize = 0;
            while (std.mem.indexOfScalarPos(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 writer.print("{s}{c}", .{
                    percent_encoded[start..percent],
                    percent_encoded_char,
                });
                start = percent + 3;
                index = percent + 3;
            }
            try writer.writeAll(percent_encoded[start..]);
        },
    } else if (comptime std.mem.eql(u8, fmt_str, "%")) switch (component) {
        .raw => |raw| try percentEncode(writer, raw, isUnreserved),
        .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
    } else if (comptime std.mem.eql(u8, fmt_str, "user")) switch (component) {
        .raw => |raw| try percentEncode(writer, raw, isUserChar),
        .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
    } else if (comptime std.mem.eql(u8, fmt_str, "password")) switch (component) {
        .raw => |raw| try percentEncode(writer, raw, isPasswordChar),
        .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
    } else if (comptime std.mem.eql(u8, fmt_str, "host")) switch (component) {
        .raw => |raw| try percentEncode(writer, raw, isHostChar),
        .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
    } else if (comptime std.mem.eql(u8, fmt_str, "path")) switch (component) {
        .raw => |raw| try percentEncode(writer, raw, isPathChar),
        .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
    } else if (comptime std.mem.eql(u8, fmt_str, "query")) switch (component) {
        .raw => |raw| try percentEncode(writer, raw, isQueryChar),
        .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
    } else if (comptime std.mem.eql(u8, fmt_str, "fragment")) switch (component) {
        .raw => |raw| try percentEncode(writer, raw, isFragmentChar),
        .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
    } else @compileError("invalid format string '" ++ fmt_str ++ "'");
}

FunctionpercentEncode[src]

pub fn percentEncode( writer: anytype, raw: []const u8, comptime isValidChar: fn (u8) bool, ) @TypeOf(writer).Error!void

Parameters

raw: []const u8
isValidChar: fn (u8) bool

Source Code

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

Source Code

Source 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,
        };
    }

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

    pub fn format(
        component: Component,
        comptime fmt_str: []const u8,
        _: std.fmt.FormatOptions,
        writer: anytype,
    ) @TypeOf(writer).Error!void {
        if (fmt_str.len == 0) {
            try writer.print("std.Uri.Component{{ .{s} = \"{}\" }}", .{
                @tagName(component),
                std.zig.fmtEscapes(switch (component) {
                    .raw, .percent_encoded => |string| string,
                }),
            });
        } else if (comptime std.mem.eql(u8, fmt_str, "raw")) switch (component) {
            .raw => |raw| try writer.writeAll(raw),
            .percent_encoded => |percent_encoded| {
                var start: usize = 0;
                var index: usize = 0;
                while (std.mem.indexOfScalarPos(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 writer.print("{s}{c}", .{
                        percent_encoded[start..percent],
                        percent_encoded_char,
                    });
                    start = percent + 3;
                    index = percent + 3;
                }
                try writer.writeAll(percent_encoded[start..]);
            },
        } else if (comptime std.mem.eql(u8, fmt_str, "%")) switch (component) {
            .raw => |raw| try percentEncode(writer, raw, isUnreserved),
            .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
        } else if (comptime std.mem.eql(u8, fmt_str, "user")) switch (component) {
            .raw => |raw| try percentEncode(writer, raw, isUserChar),
            .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
        } else if (comptime std.mem.eql(u8, fmt_str, "password")) switch (component) {
            .raw => |raw| try percentEncode(writer, raw, isPasswordChar),
            .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
        } else if (comptime std.mem.eql(u8, fmt_str, "host")) switch (component) {
            .raw => |raw| try percentEncode(writer, raw, isHostChar),
            .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
        } else if (comptime std.mem.eql(u8, fmt_str, "path")) switch (component) {
            .raw => |raw| try percentEncode(writer, raw, isPathChar),
            .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
        } else if (comptime std.mem.eql(u8, fmt_str, "query")) switch (component) {
            .raw => |raw| try percentEncode(writer, raw, isQueryChar),
            .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
        } else if (comptime std.mem.eql(u8, fmt_str, "fragment")) switch (component) {
            .raw => |raw| try percentEncode(writer, raw, isFragmentChar),
            .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded),
        } else @compileError("invalid format string '" ++ fmt_str ++ "'");
    }

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