Something went wrong. Try again.
A Zig library for Bluesky activity and feed analytics, built on Zat.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556const std = @import("std");
pub const Paths = struct { config: []const u8, cache: []const u8, state: []const u8,
pub fn init(a: std.mem.Allocator, home: ?[]const u8, config: ?[]const u8, cache: ?[]const u8, state: ?[]const u8) !Paths { return .{ .config = try base(a, config, home, ".config"), .cache = try base(a, cache, home, ".cache"), .state = try base(a, state, home, ".local/state"), }; }
pub fn snapshot(self: Paths, a: std.mem.Allocator, did: []const u8, source: []const u8, micros: i64) ![]const u8 { var hash = std.crypto.hash.sha2.Sha256.init(.{}); hash.update(did); hash.update("\x00"); hash.update(source); const digest = hash.finalResult(); const key = std.fmt.bytesToHex(digest, .lower); return std.fmt.allocPrint(a, "{s}/{s}/{d}.json", .{ self.cache, key, micros }); }};
fn base(a: std.mem.Allocator, override: ?[]const u8, home: ?[]const u8, fallback: []const u8) ![]const u8 { if (override) |path| { if (std.fs.path.isAbsolute(path)) return std.fs.path.join(a, &.{ path, "tend" }); } const path = home orelse return error.MissingHome; if (!std.fs.path.isAbsolute(path)) return error.InvalidHome; return std.fs.path.join(a, &.{ path, fallback, "tend" });}
test "XDG uses absolute overrides and ignores relative or empty values" { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const paths = try Paths.init(arena.allocator(), "/home/test", "relative", "/custom/cache", ""); try std.testing.expectEqualStrings("/home/test/.config/tend", paths.config); try std.testing.expectEqualStrings("/custom/cache/tend", paths.cache); try std.testing.expectEqualStrings("/home/test/.local/state/tend", paths.state);}
test "cache keys separate account and AppView" { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const a = arena.allocator(); const paths = try Paths.init(a, "/home/test", null, null, null); const one = try paths.snapshot(a, "did:plc:one", "did:web:first#appview", 1); const two = try paths.snapshot(a, "did:plc:one", "did:web:second#appview", 1); const three = try paths.snapshot(a, "did:plc:two", "did:web:first#appview", 1); try std.testing.expect(!std.mem.eql(u8, one, two)); try std.testing.expect(!std.mem.eql(u8, one, three));}