From c70ffd095a6de5cd5b872796a0d82a8c5afc1511 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sat, 20 Jul 2024 17:22:25 +0300 Subject: Initial commit --- src/Config.zig | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/Config.zig (limited to 'src/Config.zig') 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 @@ +const std = @import("std"); + +const Allocator = std.mem.Allocator; +const ArenaAllocator = std.heap.ArenaAllocator; +const Config = @This(); + +pub const Wrapper = struct { + arena: ArenaAllocator, + config: Config, + + pub fn deinit(self: Wrapper) void { + self.arena.deinit(); + } + + pub fn merge(self: *Wrapper, filename: []const u8) !void { + const file = try std.fs.cwd().openFile(filename, .{}); + defer file.close(); + + const allocator = self.arena.allocator(); + + var reader = std.json.reader(allocator, file.reader()); + defer reader.deinit(); + + const new_config = try std.json.parseFromTokenSourceLeaky( + Nullable, + allocator, + &reader, + .{ + .duplicate_field_behavior = .use_last, + .ignore_unknown_fields = true, + .allocate = .alloc_always, + }, + ); + + inline for (std.meta.fields(Config)) |field| { + if (@field(new_config, field.name)) |value| { + @field(self.config, field.name) = value; + } + } + } +}; + +bot_token: []const u8, +dev_group: i64, +owner: i64, + +pub fn load(parent_allocator: Allocator, filename: []const u8) !Wrapper { + const file = try std.fs.cwd().openFile(filename, .{}); + defer file.close(); + + var arena = ArenaAllocator.init(parent_allocator); + errdefer arena.deinit(); + const allocator = arena.allocator(); + + var reader = std.json.reader(allocator, file.reader()); + defer reader.deinit(); + + const config = try std.json.parseFromTokenSourceLeaky( + Config, + allocator, + &reader, + .{ + .duplicate_field_behavior = .use_last, + .ignore_unknown_fields = true, + .allocate = .alloc_always, + }, + ); + + return .{ .arena = arena, .config = config }; +} + +const Nullable = blk: { + const template = @typeInfo(Config); + var fields: [template.Struct.fields.len]std.builtin.Type.StructField = undefined; + for (template.Struct.fields, 0..) |template_field, field_idx| { + fields[field_idx] = template_field; + fields[field_idx].type = ?template_field.type; + } + var new = template; + new.Struct.fields = &fields; + new.Struct.decls = &.{}; + break :blk @Type(new); +}; -- cgit v1.2.3