~gpanders/wk

ref: 5ce1b9c4ea4e17245abfd85792d235aa3629aee2 wk/src/cmd.zig -rw-r--r-- 3.3 KiB
5ce1b9c4Greg Anders Find zettels by ID + title 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
const std = @import("std");

const zettel = @import("zettel.zig");

pub const list = @import("cmd/list.zig");
pub const new = @import("cmd/new.zig");
pub const open = @import("cmd/open.zig");
pub const preview = @import("cmd/preview.zig");
pub const search = @import("cmd/search.zig");
pub const show = @import("cmd/show.zig");
pub const tags = @import("cmd/tags.zig");

pub const Command = enum {
    List,
    New,
    Open,
    Preview,
    Search,
    Show,
    Tags,

    pub fn usage(self: Command) []const u8 {
        return switch (self) {
            .List => list.usage,
            .New => new.usage,
            .Open => open.usage,
            .Preview => preview.usage,
            .Search => search.usage,
            .Show => show.usage,
            .Tags => tags.usage,
        };
    }
};

pub fn handleCommand(command: []const u8, arg: ?[]const u8, allocator: *std.mem.Allocator) !void {
    const zettels = try zettel.getZettels(allocator);
    defer allocator.free(zettels);

    switch (try parseCommand(command)) {
        .Show => if (arg != null) {
            if (zettel.findZettel(zettels, arg.?)) |zet| {
                try show.run(allocator, zet);
            } else {
                return error.DoesNotExist;
            }
        } else {
            return error.MissingRequiredArgument;
        },
        .List => try list.run(allocator, arg, zettels),
        .Open => {
            if (arg != null) {
                if (zettel.findZettel(zettels, arg.?)) |zet| {
                    try open.run(allocator, zet);
                } else {
                    return error.DoesNotExist;
                }
            } else {
                try open.run(allocator, null);
            }
        },
        .New => if (arg != null) {
            try new.run(allocator, arg.?);
        } else {
            return error.MissingRequiredArgument;
        },
        .Search => if (arg != null) {
            try search.run(allocator, arg.?, zettels);
        } else {
            return error.MissingRequiredArgument;
        },
        .Preview => if (arg != null) {
            if (zettel.findZettel(zettels, arg.?)) |zet| {
                try preview.run(allocator, zet);
            } else {
                return error.DoesNotExist;
            }
        } else {
            return error.MissingRequiredArgument;
        },
        .Tags => try tags.run(allocator, arg, zettels),
    }
}

fn parseCommand(command: []const u8) !Command {
    if (strEq(command, &[_][]const u8{ "sh", "show" })) {
        return .Show;
    }

    if (strEq(command, &[_][]const u8{ "l", "ls", "list" })) {
        return .List;
    }

    if (strEq(command, &[_][]const u8{ "o", "open" })) {
        return .Open;
    }

    if (strEq(command, &[_][]const u8{ "n", "new" })) {
        return .New;
    }

    if (strEq(command, &[_][]const u8{ "s", "search" })) {
        return .Search;
    }

    if (strEq(command, &[_][]const u8{ "p", "pre", "prev", "preview" })) {
        return .Preview;
    }

    if (strEq(command, &[_][]const u8{ "t", "tag", "tags" })) {
        return .Tags;
    }

    return error.UnknownCommand;
}

/// Return true if the given `str` matches any of the strings in `patterns`.
fn strEq(str: []const u8, patterns: []const []const u8) bool {
    for (patterns) |pat| {
        if (std.mem.eql(u8, str, pat)) {
            return true;
        }
    }

    return false;
}