~tagglink/libjournal

ac37718e0149d45ffeb97f13fc61380f59e2b954 — Tomas Granlund 2 years ago 57d490f
made error sets explicit
1 files changed, 65 insertions(+), 35 deletions(-)

M src/journal.zig
M src/journal.zig => src/journal.zig +65 -35
@@ 6,7 6,8 @@ const epoch = std.time.epoch;
const Allocator = std.mem.Allocator;
const testing = std.testing;

const Regex = @import("zig-regex").Regex;
const regexlib = @import("zig-regex");
const Regex = regexlib.Regex;
const journal_h = @import("journal_h.zig");
const calendar = @import("calendar.zig");
const Datetime = calendar.Datetime;


@@ 52,11 53,13 @@ pub const Timestamp = struct {
    }
};

pub const RegexMatchError = error{} || Allocator.Error;

pub const RegexNodeChild = union(enum) {
    node: RegexNode,
    leaf: RegexLeaf,

    pub fn match(self: *RegexNodeChild, str: []const u8) !bool {
    pub fn match(self: *RegexNodeChild, str: []const u8) RegexMatchError!bool {
        switch (self.*) {
            .leaf => {
                return self.leaf.match(str);


@@ 88,7 91,7 @@ pub const RegexLeaf = struct {
        case_sensitive: bool = false,
    };

    pub fn match(self: *RegexLeaf, str: []const u8) !bool {
    pub fn match(self: *RegexLeaf, str: []const u8) RegexMatchError!bool {
        return self.regex.partialMatch(str);
    }



@@ 97,10 100,15 @@ pub const RegexLeaf = struct {
    }
};

pub const NodeCreateError = error{
    InvalidDescriptorType,
    NullDescriptorPointer,
} || Allocator.Error || regexlib.parse.ParseError;

pub const RegexNode = struct {
    config: Config,
    children: []RegexNodeChild,
    alloc: std.mem.Allocator,
    alloc: Allocator,

    pub const CombineMethod = enum { Or, And };



@@ 109,6 117,29 @@ pub const RegexNode = struct {
        case_sensitive: bool = false,
    };

    pub fn createChild(a: Allocator, config: RegexNode.Config, descriptor: journal_h.struct_journal_regex_node_descriptor) NodeCreateError!RegexNodeChild {
        if (descriptor.ptr == null) return error.NullDescriptorPointer;
        switch (descriptor.type) {
            journal_h.JOURNAL_NODE_DESC_TYPE_REGEX => {
                const ptr = @ptrCast([*:0]const u8, descriptor.ptr.?);
                const regex_source: []const u8 = ptr[0..std.mem.len(ptr)];
                return RegexNodeChild{ .leaf = RegexLeaf{
                    .regex_source = regex_source,
                    .regex = try Regex.compile(a, regex_source),
                    .config = RegexLeaf.Config{
                        .case_sensitive = config.case_sensitive,
                    },
                } };
            },
            journal_h.JOURNAL_NODE_DESC_TYPE_NODE => {
                const t = [*c]const journal_h.struct_journal_regex_node;
                const ptr = @ptrCast(t, @alignCast(@alignOf(t), descriptor.ptr.?));
                return RegexNodeChild{ .node = try RegexNode.create(a, ptr) };
            },
            else => return error.InvalidDescriptorType,
        }
    }

    fn freeChildren(children: []RegexNodeChild, count: usize) void {
        var i: usize = 0;
        while (i < count) : (i += 1) {


@@ 116,7 147,7 @@ pub const RegexNode = struct {
        }
    }

    pub fn create(a: std.mem.Allocator, in_node: [*c]const journal_h.struct_journal_regex_node) anyerror!RegexNode { // TODO: define error set
    pub fn create(a: Allocator, in_node: [*c]const journal_h.struct_journal_regex_node) NodeCreateError!RegexNode {
        const config = RegexNode.Config{
            .combine_method = if (in_node.*.config & journal_h.JOURNAL_NODE_CONF_COMB_OR != 0) .Or else .And,
            .case_sensitive = in_node.*.config & journal_h.JOURNAL_NODE_CONF_CASE_CARE != 0,


@@ 130,26 161,7 @@ pub const RegexNode = struct {
        errdefer freeChildren(children, i);
        while (i < child_cnt) : (i += 1) {
            const descriptor = in_node.*.children[i];
            std.debug.assert(descriptor.ptr != null);
            switch (descriptor.type) {
                journal_h.JOURNAL_NODE_DESC_TYPE_REGEX => {
                    const ptr = @ptrCast([*:0]const u8, descriptor.ptr.?);
                    const regex_source: []const u8 = ptr[0..std.mem.len(ptr)];
                    children[i] = RegexNodeChild{ .leaf = RegexLeaf{
                        .regex_source = regex_source,
                        .regex = try Regex.compile(a, regex_source),
                        .config = RegexLeaf.Config{
                            .case_sensitive = config.case_sensitive,
                        },
                    } };
                },
                journal_h.JOURNAL_NODE_DESC_TYPE_NODE => {
                    const t = [*c]const journal_h.struct_journal_regex_node;
                    const ptr = @ptrCast(t, @alignCast(@alignOf(t), descriptor.ptr.?));
                    children[i] = RegexNodeChild{ .node = try RegexNode.create(a, ptr) };
                },
                else => return error.InvalidDescriptorType,
            }
            children[i] = try createChild(a, config, descriptor);
        }

        return RegexNode{


@@ 166,7 178,7 @@ pub const RegexNode = struct {
        self.alloc.free(self.children);
    }

    pub fn match(self: *RegexNode, str: []const u8) anyerror!bool { // TODO: define error set
    pub fn match(self: *RegexNode, str: []const u8) RegexMatchError!bool {
        switch (self.config.combine_method) {
            .Or => {
                for (self.children) |_, i| {


@@ 194,7 206,7 @@ pub const Query = struct {
    from: Timestamp,
    to: Timestamp,

    pub fn create(a: std.mem.Allocator, q: [*c]journal_h.struct_journal_query) !Query {
    pub fn create(a: Allocator, q: [*c]journal_h.struct_journal_query) NodeCreateError!Query {
        return Query{
            .dir = q.*.dir[0..std.mem.len(q.*.dir)],
            .root = try RegexNode.create(a, q.*.root),


@@ 220,11 232,17 @@ pub const Result = struct {
    }
};

fn findFiledDates(
pub const CallbackError = error{
    GenericCallbackError,
};

pub const FindFiledDatesError = CallbackError || fs.File.OpenError;

pub fn findFiledDates(
    q: Query,
    comptime cb: fn (u64, anytype) anyerror!void,
    comptime cb: fn (u64, anytype) CallbackError!void,
    data: anytype,
) !void {
) FindFiledDatesError!void {
    var root_dir = try fs.openDirAbsolute(q.dir, .{ .iterate = true });
    defer root_dir.close();



@@ 274,13 292,13 @@ fn findFiledDates(
    }
}

fn countEntry(d: u64, data: anytype) anyerror!void {
fn countEntry(d: u64, data: anytype) CallbackError!void {
    _ = d;
    data.* = data.* + 1;
}

fn addEntry(d: u64, data: anytype) anyerror!void {
    try data.*.append(d);
fn addEntry(d: u64, data: anytype) CallbackError!void {
    data.*.append(d) catch return error.GenericCallbackError;
}

fn lessThan(comptime ctx: comptime_int, lhs: u64, rhs: u64) bool {


@@ 288,7 306,15 @@ fn lessThan(comptime ctx: comptime_int, lhs: u64, rhs: u64) bool {
    return lhs < rhs;
}

pub fn query(a: Allocator, q: *Query) !Result {
pub const ReaderError = error{
    StreamTooLong,
};

pub const QueryError = error{
    NoEntriesFound,
} || Allocator.Error || FindFiledDatesError || fmt.AllocPrintError || fmt.BufPrintError || std.os.ReadError || ReaderError;

pub fn query(a: Allocator, q: *Query) QueryError!Result {
    var fileCount: u32 = 0;

    try findFiledDates(q.*, countEntry, &fileCount);


@@ 364,6 390,10 @@ pub fn query(a: Allocator, q: *Query) !Result {
    return result;
}

pub const GetMatchesError = error{
    NotImplemented,
};

pub const Matches = struct {
    match_count: u32,
    matches: *u8,


@@ 383,7 413,7 @@ pub const Matches = struct {
    }
};

pub fn getMatches(a: Allocator, q: Query) !Matches {
pub fn getMatches(a: Allocator, q: Query) GetMatchesError!Matches {
    _ = a;
    _ = q;
    return error.NotImplemented;