~subsetpark/erasmus

1f1084edce6d2629569329cee6a149756e81b908 — Zach Smith 2 months ago 3e2019d
use error type, not error value
2 files changed, 43 insertions(+), 50 deletions(-)

M .gitignore
M src/note.zig
M .gitignore => .gitignore +0 -1
@@ 1,4 1,3 @@
/zig-cache
/zig-out
/tags


M src/note.zig => src/note.zig +43 -49
@@ 4,50 4,44 @@ const util = @import("./util.zig");
const mem = std.mem;
const fmt = std.fmt;

const EscapedString = struct {
    escaped: util.CharBuffer,
    escape_error: ?EscapeError = null,

    const EscapeError = enum { TerminalPeriod };

    fn init(to_escape: []const u8, allocator: mem.Allocator) !@This() {
        return EscapedString{
            .escaped = try util.CharBuffer.initCapacity(allocator, to_escape.len * 2),
        };
const EscapeError = error{ TerminalPeriod, OutOfMemory };

// Process a string and escape any delimiters for reference creation.
fn escapeAndLower(s: []const u8, allocator: mem.Allocator) !util.CharBuffer {
    // Check for illegal characters. Right now the only illegal character is a
    // terminal period, which confuses vim, so this is a bit particular.
    if (s.len > 0 and s[s.len - 1] == '.') {
        return EscapeError.TerminalPeriod;
    }

    // Process a string and escape any delimiters for reference creation.
    fn escapeAndLower(self: *@This(), s: []const u8) void {
        // Check for illegal characters. Right now the only illegal character is a
        // terminal period, which confuses vim, so this is a bit particular.
        if (s.len > 0 and s[s.len - 1] == '.') {
            self.escape_error = EscapeError.TerminalPeriod;
            return;
        }
        for (s) |char| {
            switch (char) {
                ' ' => {
                    self.escaped.appendAssumeCapacity('\\');
                },
                else => {},
            }
            const lower_char = std.ascii.toLower(char);
            self.escaped.appendAssumeCapacity(lower_char);
        }
    }
    var escaped = try util.CharBuffer.initCapacity(allocator, s.len * 2);

    fn handleErrors(self: @This()) void {
        if (self.escape_error) |escape_error| {
            switch (escape_error) {
                EscapeError.TerminalPeriod => {
                    std.debug.print("Note references can't end with a period", .{});
                    std.os.exit(1);
                },
            }
    for (s) |char| {
        switch (char) {
            ' ' => {
                escaped.appendAssumeCapacity('\\');
            },
            else => {},
        }
        const lower_char = std.ascii.toLower(char);
        escaped.appendAssumeCapacity(lower_char);
    }
};

    return escaped;
}

fn handleEscapeError(err: EscapeError) void {
    switch (err) {
        EscapeError.TerminalPeriod => {
            std.debug.print("Note references can't end with a period", .{});
            std.os.exit(1);
        },
        error.OutOfMemory => {
            std.debug.print("OOM", .{});
            std.os.exit(1);
        },
    }
}
const BufferAndBraces = struct {
    buffer: util.CharBuffer,
    offset: usize,


@@ 135,12 129,12 @@ pub const Note = struct {
                defer allocator.free(reference_lowered);

                if (mem.eql(u8, reference_lowered, self_lowered)) {
                    var escaped = try EscapedString.init(other_note.name, allocator);
                    var escaped = escapeAndLower(other_note.name, allocator) catch |err| {
                        handleEscapeError(err);
                        unreachable;
                    };

                    escaped.escapeAndLower(other_note.name);
                    escaped.handleErrors();

                    try self.backlinks.append(escaped.escaped.items);
                    try self.backlinks.append(escaped.items);
                    break;
                }
            }


@@ 246,13 240,13 @@ pub const Note = struct {

        // Escape and add forward references to note.
        for (self.references.items) |phrase| {
            var escaped = try EscapedString.init(phrase, allocator);
            defer escaped.escaped.deinit();

            escaped.escapeAndLower(phrase);
            escaped.handleErrors();
            var escaped = escapeAndLower(phrase, allocator) catch |err| {
                handleEscapeError(err);
                unreachable;
            };
            defer escaped.deinit();

            const str = escaped.escaped.items;
            const str = escaped.items;
            if (!seen.contains(str)) {
                try seen.insert(str);
                try appendRef(buf, str, allocator);