Skip to documentation
SLOP

tiny.profiling.substitute

Reference tiny.profiling substitute

Defined in tiny.profiling.

API (2)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstiny.profilingsubstitute
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallstest; no linksrc.profiling.substitutetest: profiling substitutions resolve...private; no linksrc.profiling.substitutereplacesubstituteresolve
Static calls · unresolved targets: 0 · external targets: 1.

Source: src/profiling/root.zig:43

zig
pub const substitute = @import("substitute.zig");

Source: src/profiling/substitute.zig

zig
const std = @import("std");pub const Replacement = struct {    token: []const u8,    value: []const u8,};pub fn resolve(    allocator: std.mem.Allocator,    template: []const u8,    replacements: []const Replacement,    maximum_bytes: usize,) ![]const u8 {    if (maximum_bytes == 0 or std.mem.indexOfScalar(u8, template, 0) != null) {        return error.InvalidResolvedString;    }    for (replacements) |replacement| {        if (replacement.token.len == 0 or            std.mem.indexOfScalar(u8, replacement.token, 0) != null or            std.mem.indexOfScalar(u8, replacement.value, 0) != null)        {            return error.InvalidResolvedString;        }    }    if (template.len > maximum_bytes) return error.InvalidResolvedString;    var result = template;    var owned: ?[]u8 = null;    errdefer if (owned) |bytes| allocator.free(bytes);    for (replacements) |replacement| {        const next = try replace(            allocator,            result,            replacement,            maximum_bytes,        ) orelse continue;        if (owned) |bytes| allocator.free(bytes);        result = next;        owned = next;    }    return result;}fn replace(    allocator: std.mem.Allocator,    input: []const u8,    replacement: Replacement,    maximum_bytes: usize,) !?[]u8 {    const count = std.mem.count(u8, input, replacement.token);    if (count == 0) return null;    const removed = std.math.mul(usize, count, replacement.token.len) catch        return error.InvalidResolvedString;    const added = std.math.mul(usize, count, replacement.value.len) catch        return error.InvalidResolvedString;    const base = input.len - removed;    const resolved_bytes = std.math.add(usize, base, added) catch        return error.InvalidResolvedString;    if (resolved_bytes > maximum_bytes) return error.InvalidResolvedString;    const result = try allocator.alloc(u8, resolved_bytes);    _ = std.mem.replace(        u8,        input,        replacement.token,        replacement.value,        result,    );    return result;}test "profiling substitutions resolve bounded repeated tokens once" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const result = try resolve(allocator, "{root}/{side}/{root}", &.{        .{ .token = "{root}", .value = "/tmp/{side}" },        .{ .token = "{side}", .value = "candidate" },    }, 128);    try std.testing.expectEqualStrings(        "/tmp/candidate/candidate//tmp/candidate",        result,    );    try std.testing.expectEqualStrings(        "literal",        try resolve(allocator, "literal", &.{}, 7),    );    try std.testing.expectEqualStrings(        "",        try resolve(allocator, "", &.{}, 1),    );    try std.testing.expectEqualStrings(        "12345678",        try resolve(allocator, "{value}", &.{.{            .token = "{value}",            .value = "12345678",        }}, 8),    );    try std.testing.expectError(        error.InvalidResolvedString,        resolve(allocator, "{value}", &.{.{            .token = "{value}",            .value = "123456789",        }}, 8),    );}

Audit

Definitions3
Public names3
Members2
Version26.7.0
Revisiondaab053ee433