Skip to documentation
SLOP

tiny.zen.diagnostic

Reference tiny.zen diagnostic

Defined in tiny.zen.

API (4)

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

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

Source

Source: lib/zen/src/diagnostic.zig

zig
const std = @import("std");const math = @import("math/root.zig");pub const max_page_bytes = 256;pub const max_equation_bytes = 256;pub const max_inline_bytes = 256;/// Fixed-capacity detail for a failed page, equation, heading, or inline feature.////// Supply its address through Markdown or site options. After an error, inspect/// `page()`, the feature source, `reason`, and `offset`, then call `reset` before/// reuse.pub const Diagnostic = struct {    page_buffer: [max_page_bytes]u8 = undefined,    page_len: usize = 0,    equation_buffer: [max_equation_bytes]u8 = undefined,    equation_len: usize = 0,    inline_buffer: [max_inline_bytes]u8 = undefined,    inline_len: usize = 0,    /// Short cause suitable for a repair message; empty when no detail is captured.    reason: []const u8 = "",    /// Byte offset in the original inline source, heading feature, or equation.    /// It can lie beyond a bounded or sanitized captured excerpt.    offset: usize = 0,    /// Returns the page path, truncated with an ellipsis if needed.    pub fn page(self: *const Diagnostic) []const u8 {        return self.page_buffer[0..self.page_len];    }    /// Returns the captured equation, truncated with an ellipsis if needed.    pub fn equation(self: *const Diagnostic) []const u8 {        return self.equation_buffer[0..self.equation_len];    }    /// Returns a bounded UTF-8-safe source prefix for context, not indexing.    /// Invalid bytes become `?` and excess source ends in `...`.    pub fn inlineSource(self: *const Diagnostic) []const u8 {        return self.inline_buffer[0..self.inline_len];    }    /// Clears captured detail before a retry or unrelated operation.    pub fn reset(self: *Diagnostic) void {        self.* = .{};    }    pub fn setPage(self: *Diagnostic, path: []const u8) void {        self.page_len = copyEllipsized(&self.page_buffer, path);    }    pub fn setEquation(self: *Diagnostic, source: []const u8, detail: math.Diagnostic) void {        self.equation_len = copyEllipsized(&self.equation_buffer, source);        self.inline_len = 0;        self.reason = detail.reason;        self.offset = detail.offset;    }    pub fn setHeading(self: *Diagnostic, reason: []const u8, offset: usize) void {        self.equation_len = 0;        self.inline_len = 0;        self.reason = reason;        self.offset = offset;    }    pub fn setInline(self: *Diagnostic, source: []const u8, reason: []const u8, offset: usize) void {        self.equation_len = 0;        self.inline_len = copyEllipsized(&self.inline_buffer, source);        self.reason = reason;        self.offset = offset;    }};fn copyEllipsized(buffer: []u8, text: []const u8) usize {    std.debug.assert(buffer.len >= 3);    const payload_limit = if (text.len > buffer.len) buffer.len - 3 else buffer.len;    var source_index: usize = 0;    var output_index: usize = 0;    while (source_index < text.len) {        const sequence_length = std.unicode.utf8ByteSequenceLength(text[source_index]) catch 1;        const sequence_end = @min(source_index + sequence_length, text.len);        const sequence = text[source_index..sequence_end];        const valid = sequence.len == sequence_length and std.unicode.utf8ValidateSlice(sequence);        const replacement = if (valid) sequence else "?";        if (output_index + replacement.len > payload_limit) break;        @memcpy(buffer[output_index..][0..replacement.len], replacement);        output_index += replacement.len;        source_index += if (valid) sequence_length else 1;    }    if (source_index < text.len) {        @memcpy(buffer[output_index..][0..3], "...");        output_index += 3;    }    std.debug.assert(output_index <= buffer.len);    return output_index;}test "diagnostic captures page and equation detail" {    var diagnostic: Diagnostic = .{};    try std.testing.expectEqualStrings("", diagnostic.page());    try std.testing.expectEqualStrings("", diagnostic.equation());    try std.testing.expectEqualStrings("", diagnostic.inlineSource());    diagnostic.setPage("writing/mathcheck.md");    diagnostic.setEquation("\\frac{1}", .{ .reason = "missing argument", .offset = 8 });    try std.testing.expectEqualStrings("writing/mathcheck.md", diagnostic.page());    try std.testing.expectEqualStrings("\\frac{1}", diagnostic.equation());    try std.testing.expectEqualStrings("missing argument", diagnostic.reason);    try std.testing.expectEqual(@as(usize, 8), diagnostic.offset);    diagnostic.setInline("[label](/missing", "link target is missing closing ')'", 7);    try std.testing.expectEqualStrings("", diagnostic.equation());    try std.testing.expectEqualStrings("[label](/missing", diagnostic.inlineSource());    try std.testing.expectEqualStrings("link target is missing closing ')'", diagnostic.reason);    try std.testing.expectEqual(@as(usize, 7), diagnostic.offset);    diagnostic.setHeading("duplicate heading anchor", 17);    try std.testing.expectEqualStrings("writing/mathcheck.md", diagnostic.page());    try std.testing.expectEqualStrings("", diagnostic.equation());    try std.testing.expectEqualStrings("", diagnostic.inlineSource());    try std.testing.expectEqualStrings("duplicate heading anchor", diagnostic.reason);    try std.testing.expectEqual(@as(usize, 17), diagnostic.offset);    diagnostic.reset();    try std.testing.expectEqualStrings("", diagnostic.page());    try std.testing.expectEqualStrings("", diagnostic.reason);}test "diagnostic truncates long captures with an ellipsis" {    var diagnostic: Diagnostic = .{};    const long = @as([(300) * ("x").len]u8, @bitCast(@as([300][("x").len]u8, @splat(("x")[0..("x").len].*))));    diagnostic.setEquation(&long, .{ .reason = "unknown command", .offset = 280 });    try std.testing.expectEqual(@as(usize, max_equation_bytes), diagnostic.equation().len);    try std.testing.expect(std.mem.endsWith(u8, diagnostic.equation(), "..."));    try std.testing.expectEqual(@as(usize, 280), diagnostic.offset);    diagnostic.setInline(&long, "link target is missing closing ')'", 280);    try std.testing.expectEqual(@as(usize, max_inline_bytes), diagnostic.inlineSource().len);    try std.testing.expect(std.mem.endsWith(u8, diagnostic.inlineSource(), "..."));    try std.testing.expectEqual(@as(usize, 280), diagnostic.offset);}test "diagnostic truncation preserves valid UTF-8 and replaces invalid bytes" {    var diagnostic: Diagnostic = .{};    var source: [max_inline_bytes + 8]u8 = @splat('x');    @memcpy(source[252..254], "ω");    diagnostic.setInline(&source, "invalid inline source", 252);    try std.testing.expect(std.unicode.utf8ValidateSlice(diagnostic.inlineSource()));    try std.testing.expectEqual(@as(usize, 255), diagnostic.inlineSource().len);    try std.testing.expect(std.mem.endsWith(u8, diagnostic.inlineSource(), "..."));    try std.testing.expectEqual(@as(u8, 'x'), diagnostic.inlineSource()[251]);    const invalid = [_]u8{ 'a', 0xff, 'b' };    diagnostic.setInline(&invalid, "invalid inline source", 1);    try std.testing.expectEqualStrings("a?b", diagnostic.inlineSource());}

Source: lib/zen/src/root.zig:17

zig
/// Fixed-capacity source-local failure detail.pub const diagnostic = @import("diagnostic.zig");

Audit

Definitions4
Public names4
Members0
Version26.7.0
Revisiondaab053ee433