atproto pds in zig pds.zat.dev
pds atproto
Something went wrong. Try again.
Zig
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869const std = @import("std");const zat = @import("zat");
pub const Error = error{ ClockIdOutOfRange, TidTooShort, TidTooLong, InvalidTidChar,};
pub const encoded_len = 13;const alphabet = "234567abcdefghijklmnopqrstuvwxyz";
/// ATProto TID generator.////// A TID is a 13-character sortable base32 string containing a microsecond/// timestamp plus a 10-bit clock id. This module does not own clock state; the/// caller provides time and clock id so tests and storage layers can control/// monotonicity.pub fn encode(timestamp_us: u64, clock_id: u16) Error![encoded_len]u8 { if (clock_id > 1023) return Error.ClockIdOutOfRange; return zat.Tid.fromTimestamp(timestamp_us, @intCast(clock_id)).raw;}
pub fn decode(tid: []const u8) Error!u64 { if (tid.len < encoded_len) return Error.TidTooShort; if (tid.len > encoded_len) return Error.TidTooLong;
const parsed = zat.Tid.parse(tid) orelse return Error.InvalidTidChar; return (parsed.timestamp() << 10) | parsed.clockId();}
pub fn timestampMicros(tid: []const u8) Error!u64 { if (tid.len < encoded_len) return Error.TidTooShort; if (tid.len > encoded_len) return Error.TidTooLong; return (zat.Tid.parse(tid) orelse return Error.InvalidTidChar).timestamp();}
pub fn clockId(tid: []const u8) Error!u16 { if (tid.len < encoded_len) return Error.TidTooShort; if (tid.len > encoded_len) return Error.TidTooLong; return (zat.Tid.parse(tid) orelse return Error.InvalidTidChar).clockId();}
fn decodeChar(c: u8) Error!u6 { for (alphabet, 0..) |candidate, i| { if (candidate == c) return @intCast(i); } return Error.InvalidTidChar;}
test "encodes sortable tids" { const a = try encode(1_700_000_000_000_000, 0); const b = try encode(1_700_000_000_000_001, 0); try std.testing.expect(std.mem.lessThan(u8, &a, &b));}
test "round trips timestamp and clock id" { const tid = try encode(1_700_000_123_456_789, 42); try std.testing.expectEqual(@as(u64, 1_700_000_123_456_789), try timestampMicros(&tid)); try std.testing.expectEqual(@as(u16, 42), try clockId(&tid));}
test "rejects malformed tids" { try std.testing.expectError(Error.TidTooShort, decode("abc")); try std.testing.expectError(Error.TidTooLong, decode("abcdefghijklmn")); try std.testing.expectError(Error.InvalidTidChar, decode("0000000000000"));}