diff options
| author | 2024-07-20 17:22:25 +0300 | |
|---|---|---|
| committer | 2024-07-20 17:22:25 +0300 | |
| commit | c70ffd095a6de5cd5b872796a0d82a8c5afc1511 (patch) | |
| tree | 56183274b05a294e357bad4d06b523472a1c4a4a /src/Config.zig | |
| download | ukkobot-c70ffd095a6de5cd5b872796a0d82a8c5afc1511.tar.gz ukkobot-c70ffd095a6de5cd5b872796a0d82a8c5afc1511.tar.xz ukkobot-c70ffd095a6de5cd5b872796a0d82a8c5afc1511.zip | |
Initial commit
Diffstat (limited to 'src/Config.zig')
| -rw-r--r-- | src/Config.zig | 83 |
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 @@ | |||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | const Allocator = std.mem.Allocator; | ||
| 4 | const ArenaAllocator = std.heap.ArenaAllocator; | ||
| 5 | const Config = @This(); | ||
| 6 | |||
| 7 | pub 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 | |||
| 43 | bot_token: []const u8, | ||
| 44 | dev_group: i64, | ||
| 45 | owner: i64, | ||
| 46 | |||
| 47 | pub 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 | |||
| 72 | const 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 | }; | ||