1// https://github.com/memcached/memcached/wiki/Commands
 2// https://ziglang.org/documentation/master/std/#std.hash_map.HashMap
 3
 4const std = @import("std");
 5
 6const Error = error{
 7    Failed,
 8    KeyNotFound,
 9};
10
11const Store = struct {
12    data: std.StringHashMap([]const u8),
13
14    pub fn set(self: *Store, key: []const u8, value: []const u8) !void {
15        self.data.put(key, value) catch |err| {
16            std.log.err("Failed adding key `{s}` with error {}", .{ key, err });
17            return error.Failed;
18        };
19    }
20
21    pub fn get(self: *Store, key: []const u8) ![]const u8 {
22        if (self.data.get(key)) |value| {
23            return value;
24        }
25        return error.KeyNotFound;
26    }
27
28    pub fn del(self: *Store, key: []const u8) !void {
29        if (!self.data.remove(key)) {
30            std.log.err("Failed deleting key `{s}`", .{key});
31            return error.KeyNotFound;
32        }
33    }
34};
35
36pub fn main() !void {
37    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
38    defer arena.deinit();
39    var allocator = arena.allocator();
40
41    var store = Store{ .data = std.StringHashMap([]const u8).init(allocator) };
42    defer store.data.deinit();
43
44    // Setting new key.
45    {
46        const key = "johhny";
47        try store.set(key, "blaze");
48    }
49
50    // Retrieving back existing key if we know it will never return an error.
51    {
52        const key = "johhny";
53        const result = store.get(key) catch unreachable;
54        std.log.info("Value: {s}", .{result});
55    }
56
57    // Retrieving back the value and handling errors.
58    {
59        const key = "unknown";
60        if (store.get(key)) |val| {
61            std.log.info("Value: {s}", .{val});
62        } else |err| {
63            std.log.err("Error: {any}", .{err});
64        }
65    }
66
67    // Retrieving back key that does not exist and handling specific errors.
68    {
69        const key = "unknown";
70        if (store.get(key)) |val| {
71            std.log.info("Value: {s}", .{val});
72        } else |err| switch (err) {
73            error.KeyNotFound => {
74                std.log.err("Key `{s}` was not found", .{key});
75            },
76        }
77    }
78
79    // Deleting existing key.
80    {
81        const key = "johhny";
82        try store.del(key);
83    }
84
85    // Retrieving back the value and handling errors.
86    {
87        const key = "johnny";
88        if (store.get(key)) |val| {
89            std.log.info("Value: {s}", .{val});
90        } else |err| {
91            std.log.err("Error: {any}", .{err});
92        }
93    }
94}