const std = @import("std"); const kf = @import("known-folders"); const Auth = @import("st").http.Auth; pub const Config = struct { auth: Auth = .{ .account = "Bearer ", .agent = "Bearer ", }, db: DBConfig = .{ .path = "./space.db", .pool_size = 5, }, pub fn updateAgentToken(self: *Config, token: []const u8) void { self.auth.agent = "Bearer " ++ token; } }; pub const DBConfig = struct { path: []const u8, pool_size: u32, }; const log = std.log.scoped(.agent); pub fn load(io: std.Io, allocator: std.mem.Allocator, environ: *std.process.Environ.Map) !Config { log.debug("Loading config", .{}); const dir = try kf.open( io, allocator, environ.*, .roaming_configuration, .{ .follow_symlinks = true }, ) orelse return error.NoConfigFolder; var file: ?std.Io.File = null; defer if (file) |f| f.close(io); _ = dir.statFile(io, "space/config.zon", .{ .follow_symlinks = true }) catch { file = try create(io, dir); }; if (file == null) file = try dir.openFile(io, "space/config.zon", .{}); const stat = try file.?.stat(io); const source = try allocator.allocSentinel(u8, stat.size, 0); defer allocator.free(source); var buffer: [64]u8 = undefined; var reader = file.?.reader(io, &buffer); try reader.interface.readSliceAll(source); return std.zon.parse.fromSliceAlloc(Config, allocator, source, null, .{}); } pub fn create(io: std.Io, dir: std.Io.Dir) !std.Io.File { log.warn("Creating new config file", .{}); const config = Config{}; try dir.createDirPath(io, "space"); const file = try dir.createFile(io, "space/config.zon", .{ .read = true }); var buffer: [64]u8 = undefined; var writer = file.writer(io, &buffer); try std.zon.stringify.serializeArbitraryDepth(config, .{}, &writer.interface); try writer.interface.flush(); return file; } pub fn free(allocator: std.mem.Allocator, config: Config) void { std.zon.parse.free(allocator, config); }