summaryrefslogtreecommitdiff
path: root/src/Config.zig
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2024-07-20 17:22:25 +0300
committerGravatar Uko Kokņevičs2024-07-20 17:22:25 +0300
commitc70ffd095a6de5cd5b872796a0d82a8c5afc1511 (patch)
tree56183274b05a294e357bad4d06b523472a1c4a4a /src/Config.zig
downloadukkobot-c70ffd095a6de5cd5b872796a0d82a8c5afc1511.tar.gz
ukkobot-c70ffd095a6de5cd5b872796a0d82a8c5afc1511.tar.xz
ukkobot-c70ffd095a6de5cd5b872796a0d82a8c5afc1511.zip
Initial commit
Diffstat (limited to 'src/Config.zig')
-rw-r--r--src/Config.zig83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/Config.zig b/src/Config.zig
new file mode 100644
index 0000000..4deebbc
--- /dev/null
+++ b/src/Config.zig
@@ -0,0 +1,83 @@
1const std = @import("std");
2
3const Allocator = std.mem.Allocator;
4const ArenaAllocator = std.heap.ArenaAllocator;
5const Config = @This();
6
7pub const Wrapper = struct {
8 arena: ArenaAllocator,
9 config: Config,
10
11 pub fn deinit(self: Wrapper) void {
12 self.arena.deinit();
13 }
14
15 pub fn merge(self: *Wrapper, filename: []const u8) !void {
16 const file = try std.fs.cwd().openFile(filename, .{});
17 defer file.close();
18
19 const allocator = self.arena.allocator();
20
21 var reader = std.json.reader(allocator, file.reader());
22 defer reader.deinit();
23
24 const new_config = try std.json.parseFromTokenSourceLeaky(
25 Nullable,
26 allocator,
27 &reader,
28 .{
29 .duplicate_field_behavior = .use_last,
30 .ignore_unknown_fields = true,
31 .allocate = .alloc_always,
32 },
33 );
34
35 inline for (std.meta.fields(Config)) |field| {
36 if (@field(new_config, field.name)) |value| {
37 @field(self.config, field.name) = value;
38 }
39 }
40 }
41};
42
43bot_token: []const u8,
44dev_group: i64,
45owner: i64,
46
47pub fn load(parent_allocator: Allocator, filename: []const u8) !Wrapper {
48 const file = try std.fs.cwd().openFile(filename, .{});
49 defer file.close();
50
51 var arena = ArenaAllocator.init(parent_allocator);
52 errdefer arena.deinit();
53 const allocator = arena.allocator();
54
55 var reader = std.json.reader(allocator, file.reader());
56 defer reader.deinit();
57
58 const config = try std.json.parseFromTokenSourceLeaky(
59 Config,
60 allocator,
61 &reader,
62 .{
63 .duplicate_field_behavior = .use_last,
64 .ignore_unknown_fields = true,
65 .allocate = .alloc_always,
66 },
67 );
68
69 return .{ .arena = arena, .config = config };
70}
71
72const Nullable = blk: {
73 const template = @typeInfo(Config);
74 var fields: [template.Struct.fields.len]std.builtin.Type.StructField = undefined;
75 for (template.Struct.fields, 0..) |template_field, field_idx| {
76 fields[field_idx] = template_field;
77 fields[field_idx].type = ?template_field.type;
78 }
79 var new = template;
80 new.Struct.fields = &fields;
81 new.Struct.decls = &.{};
82 break :blk @Type(new);
83};